#ifndef WOLF_NULLABLE_H
#define WOLF_NULLABLE_H
+/**wrapper around scalar values that makes them NULL-able, i.e. the virtual value NULL is added to the range of the wrapped value; wrapped classes must have a default constructor and =, == and != operators*/
template<class T>class Nullable
{
public:
+ /**creates a NULL value*/
Nullable(){isnull=true;elem=T();}
+ /**creates a wrapped non-NULL value that is equivalent to the original*/
Nullable(const T&t){isnull=false;elem=t;}
+ /**copies a nullable value*/
Nullable(const Nullable<T>&t){isnull=t.isnull;elem=t.elem;}
+ /**makes this instance non-NULL and equivalent to the given value*/
Nullable<T>& operator=(const T&t){isnull=false;elem=t;return *this;}
+ /**copies the given nullable value*/
Nullable<T>& operator=(const Nullable<T>&t){isnull=t.isnull;elem=t.elem;return *this;}
+ /**returns whether this instance is NULL*/
bool isNull()const{return isnull;}
+ /**converts this nullable to the original wrapped class - uses the default constructor if it is NULL*/
operator T()const{if(isnull)return T();else return elem;}
+ /**returns a reference to the wrapped value - the result is undefined if it us currently NULL*/
T& value(){return elem;}
+ /**returns the original value, uses an instance created with the default constructor if it is currently NULL*/
T value()const{if(isnull)return T();else return elem;}
- bool operator==(const T&t){if(isnull)return false;else return elem == t;}
- bool operator!=(const T&t){if(isnull)return true;else return elem != t;}
+ /**compares this instance with a value of the original class, NULL is different from ANY instance of the original class*/
+ bool operator==(const T&t)const{if(isnull)return false;else return elem == t;}
+ /**compares this instance with a value of the original class, NULL is different from ANY instance of the original class*/
+ bool operator!=(const T&t)const{if(isnull)return true;else return elem != t;}
- bool operator==(const Nullable<T>&t){
+ /**compares two nullable instances, if both are NULL it returns true*/
+ bool operator==(const Nullable<T>&t)const{
if(isnull != t.isnull)return false;
if(isnull)return true;
else return elem == t.elem;}
- bool operator!=(const Nullable<T>&t){
+ /**compares two nullable instances, if both are NULL it returns false*/
+ bool operator!=(const Nullable<T>&t)const{
if(isnull != t.isnull)return true;
if(isnull)return false;
else return elem != t.elem;}
T elem;
};
+//convenience wrappers
typedef Nullable<int> Int;
typedef Nullable<qint32> Int32;
typedef Nullable<qint64> Int64;
typedef Nullable<quint64> UInt64;
typedef Nullable<QString> NString;
+inline bool operator==(Int64 i1,int i2){return i1.operator==(i2);}
+inline bool operator==(UInt32 i1,int i2){return i1.operator==(i2);}
+inline bool operator==(UInt64 i1,int i2){return i1.operator==(i2);}
+inline bool operator==(UInt64 i1,unsigned int i2){return i1.operator==(i2);}
+
#endif