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&()
00228 {
00229 if (is_null)
00230 return data = Behavior::null_is();
00231 else
00232 return data;
00233 }
00234
00238 Null& operator =(const Type& x)
00239 {
00240 data = x;
00241 is_null = false;
00242 return *this;
00243 }
00244
00249 Null& operator =(const null_type& n)
00250 {
00251 is_null = true;
00252 return *this;
00253 }
00254
00260 bool operator ==(const Null<Type>& rhs) const
00261 {
00262 if (is_null && rhs.is_null) {
00263 return true;
00264 }
00265 else if (is_null != rhs.is_null) {
00266 return false;
00267 }
00268 else {
00269 return data == rhs.data;
00270 }
00271 }
00272
00276 bool operator ==(const null_type&) const { return is_null; }
00277
00279 bool operator !=(const Null<Type>& rhs) const
00280 { return !(*this == rhs); }
00281
00283 bool operator !=(const null_type& rhs) const
00284 { return !(*this == rhs); }
00285
00291 bool operator <(const Null<Type>& rhs) const
00292 {
00293 if (is_null) {
00294 return !rhs.is_null;
00295 }
00296 else if (rhs.is_null) {
00297 return false;
00298 }
00299 else {
00300 return data < rhs.data;
00301 }
00302 }
00303
00308 bool operator <(const null_type&) const { return false; }
00309 };
00310
00311
00312 #if !defined(DOXYGEN_IGNORE)
00313
00314
00315
00316 template <> class Null<void>
00317 {
00318 public:
00319 bool is_null;
00320 typedef void value_type;
00321
00322 Null() :
00323 is_null(false)
00324 {
00325 }
00326
00327 Null(const null_type&) :
00328 is_null(true)
00329 {
00330 }
00331
00332 Null& operator =(const null_type&)
00333 {
00334 is_null = true;
00335 return *this;
00336 }
00337 };
00338
00339 #endif // !defined(DOXYGEN_IGNORE)
00340
00341
00345 template <class Type, class Behavior>
00346 inline std::ostream& operator <<(std::ostream& o,
00347 const Null<Type, Behavior>& n)
00348 {
00349 if (n.is_null)
00350 return Behavior::null_ostr(o);
00351 else
00352 return o << n.data;
00353 }
00354
00355 }
00356
00357 #endif