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> class Null
00170 {
00171 public:
00173 Type data;
00174
00178 bool is_null;
00179
00182 typedef Type value_type;
00183
00188 Null() :
00189 is_null(false)
00190 {
00191 }
00192
00200 Null(const Type& x) :
00201 data(x),
00202 is_null(false)
00203 {
00204 }
00205
00214 Null(const null_type&) :
00215 is_null(true)
00216 {
00217 }
00218
00226 operator Type&()
00227 {
00228 if (is_null)
00229 return data = Behavior::null_is();
00230 else
00231 return data;
00232 }
00233
00237 Null& operator =(const Type& x)
00238 {
00239 data = x;
00240 is_null = false;
00241 return *this;
00242 }
00243
00248 Null& operator =(const null_type& n)
00249 {
00250 is_null = true;
00251 return *this;
00252 }
00253
00259 bool operator ==(const Null<Type>& rhs) const
00260 {
00261 if (is_null && rhs.is_null) {
00262 return true;
00263 }
00264 else if (is_null != rhs.is_null) {
00265 return false;
00266 }
00267 else {
00268 return data == rhs.data;
00269 }
00270 }
00271
00275 bool operator ==(const null_type&) const { return is_null; }
00276
00278 bool operator !=(const Null<Type>& rhs) const
00279 { return !(*this == rhs); }
00280
00282 bool operator !=(const null_type& rhs) const
00283 { return !(*this == rhs); }
00284
00290 bool operator <(const Null<Type>& rhs) const
00291 {
00292 if (is_null && rhs.is_null) {
00293 return false;
00294 }
00295 else if (is_null && !rhs.is_null) {
00296 return true;
00297 }
00298 else {
00299 return data < rhs.data;
00300 }
00301 }
00302
00307 bool operator <(const null_type&) const { return false; }
00308 };
00309
00310
00311 #if !defined(DOXYGEN_IGNORE)
00312
00313
00314
00315 template <> class Null<void>
00316 {
00317 public:
00318 bool is_null;
00319 typedef void value_type;
00320
00321 Null() :
00322 is_null(false)
00323 {
00324 }
00325
00326 Null(const null_type&) :
00327 is_null(true)
00328 {
00329 }
00330
00331 Null& operator =(const null_type&)
00332 {
00333 is_null = true;
00334 return *this;
00335 }
00336 };
00337
00338 #endif // !defined(DOXYGEN_IGNORE)
00339
00340
00344 template <class Type, class Behavior>
00345 inline std::ostream& operator <<(std::ostream& o,
00346 const Null<Type, Behavior>& n)
00347 {
00348 if (n.is_null)
00349 return Behavior::null_ostr(o);
00350 else
00351 return o << n.data;
00352 }
00353
00354 }
00355
00356 #endif