1 | #pragma once |
2 | |
3 | #include <mysqlxx/Exception.h> |
4 | |
5 | |
6 | namespace mysqlxx |
7 | { |
8 | |
9 | |
10 | struct NullType {}; |
11 | const NullType null = {}; |
12 | |
13 | |
14 | /** Store NULL-able types from MySQL. |
15 | * Usage example: |
16 | * mysqlxx::Null<int> x = mysqlxx::null; |
17 | * std::cout << (x.isNull() ? "Ok." : "Fail.") << std::endl; |
18 | * x = 10; |
19 | */ |
20 | template <typename T> |
21 | class Null |
22 | { |
23 | public: |
24 | T data {}; |
25 | bool is_null = true; |
26 | |
27 | Null() : is_null(true) {} |
28 | Null(const Null<T> &) = default; |
29 | Null(Null<T> &&) noexcept = default; |
30 | Null(NullType data) : is_null(true) {} |
31 | explicit Null(const T & data_) : data(data_), is_null(false) {} |
32 | |
33 | operator T & () |
34 | { |
35 | if (is_null) |
36 | throw Exception("Value is NULL" ); |
37 | return data; |
38 | } |
39 | |
40 | operator const T & () const |
41 | { |
42 | if (is_null) |
43 | throw Exception("Value is NULL" ); |
44 | return data; |
45 | } |
46 | |
47 | Null<T> & operator= (Null<T> &&) noexcept = default; |
48 | Null<T> & operator= (const Null<T> &) = default; |
49 | Null<T> & operator= (const T & data_) { is_null = false; data = data_; return *this; } |
50 | Null<T> & operator= (const NullType other) { is_null = true; data = T(); return *this; } |
51 | |
52 | bool isNull() const { return is_null; } |
53 | |
54 | bool operator< (const Null<T> & other) const |
55 | { |
56 | return is_null < other.is_null |
57 | || (is_null == other.is_null && data < other.data); |
58 | } |
59 | |
60 | bool operator< (const NullType other) const { return false; } |
61 | |
62 | bool operator== (const Null<T> & other) const |
63 | { |
64 | return is_null == other.is_null && data == other.data; |
65 | } |
66 | |
67 | bool operator== (const T & other) const |
68 | { |
69 | return !is_null && data == other; |
70 | } |
71 | |
72 | bool operator== (const NullType other) const { return is_null; } |
73 | |
74 | bool operator!= (const Null<T> & other) const |
75 | { |
76 | return !(*this == other); |
77 | } |
78 | |
79 | bool operator!= (const NullType other) const { return !is_null; } |
80 | |
81 | bool operator!= (const T & other) const |
82 | { |
83 | return is_null || data != other; |
84 | } |
85 | }; |
86 | |
87 | |
88 | template<typename T> |
89 | T getValueFromNull(const Null<T> & maybe) |
90 | { |
91 | if (maybe.isNull()) |
92 | return {}; |
93 | return maybe; |
94 | } |
95 | |
96 | } |
97 | |