00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MYSQLPP_NULL_H
00033 #define MYSQLPP_NULL_H
00034
00035 #include "exceptions.h"
00036
00037 #include <iostream>
00038 #include <string>
00039
00040 namespace mysqlpp {
00041
00042 extern const std::string null_str;
00043
00044
00049 class MYSQLPP_EXPORT null_type
00050 {
00051 protected:
00052 #if !defined(DOXYGEN_IGNORE)
00053
00054 template <typename CannotConvertNullToAnyOtherDataType>
00055 operator CannotConvertNullToAnyOtherDataType() const
00056 {
00057 return CannotConvertNullToAnyOtherDataType();
00058 }
00059 #endif // !defined(DOXYGEN_IGNORE)
00060 };
00061
00084 const null_type null = null_type();
00085
00086
00094 struct NullIsNull
00095 {
00096 #if !defined(DOXYGEN_IGNORE)
00097
00098 static null_type null_is() { return null; }
00099
00100 static std::ostream& null_ostr(std::ostream& o)
00101 {
00102 o << "(NULL)";
00103 return o;
00104 }
00105 #endif // !defined(DOXYGEN_IGNORE)
00106 };
00107
00108
00115 struct NullIsZero
00116 {
00117 #if !defined(DOXYGEN_IGNORE)
00118
00119 static int null_is() { return 0; }
00120
00121 static std::ostream& null_ostr(std::ostream& o)
00122 {
00123 o << 0;
00124 return o;
00125 }
00126 #endif // !defined(DOXYGEN_IGNORE)
00127 };
00128
00135 struct NullIsBlank
00136 {
00137 #if !defined(DOXYGEN_IGNORE)
00138
00139 static const char *null_is() { return ""; }
00140
00141 static std::ostream& null_ostr(std::ostream& o)
00142 {
00143 o << "";
00144 return o;
00145 }
00146 #endif // !defined(DOXYGEN_IGNORE)
00147 };
00148
00149
00169 template <class Type, class Behavior = NullIsNull>
00170 class Null
00171 {
00172 public:
00174 Type data;
00175
00179 bool is_null;
00180
00183 typedef Type value_type;
00184
00189 Null() :
00190 is_null(false)
00191 {
00192 }
00193
00201 Null(const Type& x) :
00202 data(x),
00203 is_null(false)
00204 {
00205 }
00206
00215 Null(const null_type&) :
00216 is_null(true)
00217 {
00218 }
00219
00227 operator Type() const
00228 {
00229 if (is_null) {
00230 return Behavior::null_is();
00231 }
00232 else {
00233 return data;
00234 }
00235 }
00236
00240 Null& operator =(const Type& x)
00241 {
00242 data = x;
00243 is_null = false;
00244 return *this;
00245 }
00246
00251 Null& operator =(const null_type& n)
00252 {
00253 is_null = true;
00254 return *this;
00255 }
00256
00262 bool operator ==(const Null<Type>& rhs) const
00263 {
00264 if (is_null && rhs.is_null) {
00265 return true;
00266 }
00267 else if (is_null != rhs.is_null) {
00268 return false;
00269 }
00270 else {
00271 return data == rhs.data;
00272 }
00273 }
00274
00278 bool operator ==(const null_type&) const { return is_null; }
00279
00281 bool operator !=(const Null<Type>& rhs) const
00282 { return !(*this == rhs); }
00283
00285 bool operator !=(const null_type& rhs) const
00286 { return !(*this == rhs); }
00287
00293 bool operator <(const Null<Type>& rhs) const
00294 {
00295 if (is_null) {
00296 return !rhs.is_null;
00297 }
00298 else if (rhs.is_null) {
00299 return false;
00300 }
00301 else {
00302 return data < rhs.data;
00303 }
00304 }
00305
00310 bool operator <(const null_type&) const { return false; }
00311 };
00312
00313
00314 #if !defined(DOXYGEN_IGNORE)
00315
00316
00317
00318 template <> class Null<void>
00319 {
00320 public:
00321 bool is_null;
00322 typedef void value_type;
00323
00324 Null() :
00325 is_null(false)
00326 {
00327 }
00328
00329 Null(const null_type&) :
00330 is_null(true)
00331 {
00332 }
00333
00334 Null& operator =(const null_type&)
00335 {
00336 is_null = true;
00337 return *this;
00338 }
00339 };
00340
00341 #endif // !defined(DOXYGEN_IGNORE)
00342
00343
00347 template <class Type, class Behavior>
00348 inline std::ostream& operator <<(std::ostream& o,
00349 const Null<Type, Behavior>& n)
00350 {
00351 if (n.is_null)
00352 return Behavior::null_ostr(o);
00353 else
00354 return o << n.data;
00355 }
00356
00357 }
00358
00359 #endif