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 data(),
00191 is_null(false)
00192 {
00193 }
00194
00202 Null(const Type& x) :
00203 data(x),
00204 is_null(false)
00205 {
00206 }
00207
00216 Null(const null_type&) :
00217 data(),
00218 is_null(true)
00219 {
00220 }
00221
00229 operator Type() const
00230 {
00231 if (is_null) {
00232 return Behavior::null_is();
00233 }
00234 else {
00235 return data;
00236 }
00237 }
00238
00242 Null& operator =(const Type& x)
00243 {
00244 data = x;
00245 is_null = false;
00246 return *this;
00247 }
00248
00253 Null& operator =(const null_type&)
00254 {
00255 is_null = true;
00256 return *this;
00257 }
00258
00264 bool operator ==(const Null<Type>& rhs) const
00265 {
00266 if (is_null && rhs.is_null) {
00267 return true;
00268 }
00269 else if (is_null != rhs.is_null) {
00270 return false;
00271 }
00272 else {
00273 return data == rhs.data;
00274 }
00275 }
00276
00280 bool operator ==(const null_type&) const { return is_null; }
00281
00283 bool operator !=(const Null<Type>& rhs) const
00284 { return !(*this == rhs); }
00285
00287 bool operator !=(const null_type& rhs) const
00288 { return !(*this == rhs); }
00289
00295 bool operator <(const Null<Type>& rhs) const
00296 {
00297 if (is_null) {
00298 return !rhs.is_null;
00299 }
00300 else if (rhs.is_null) {
00301 return false;
00302 }
00303 else {
00304 return data < rhs.data;
00305 }
00306 }
00307
00312 bool operator <(const null_type&) const { return false; }
00313 };
00314
00315
00316 #if !defined(DOXYGEN_IGNORE)
00317
00318
00319
00320 template <> class Null<void>
00321 {
00322 public:
00323 bool is_null;
00324 typedef void value_type;
00325
00326 Null() :
00327 is_null(false)
00328 {
00329 }
00330
00331 Null(const null_type&) :
00332 is_null(true)
00333 {
00334 }
00335
00336 Null& operator =(const null_type&)
00337 {
00338 is_null = true;
00339 return *this;
00340 }
00341 };
00342
00343 #endif // !defined(DOXYGEN_IGNORE)
00344
00345
00349 template <class Type, class Behavior>
00350 inline std::ostream& operator <<(std::ostream& o,
00351 const Null<Type, Behavior>& n)
00352 {
00353 if (n.is_null)
00354 return Behavior::null_ostr(o);
00355 else
00356 return o << n.data;
00357 }
00358
00359 }
00360
00361 #endif