c++ Nullable类实现

来源:互联网 发布:欧洲杯决赛数据 编辑:程序博客网 时间:2024/06/02 00:05

template<class _Friend, typename _Ty >
class Property
{
friend _Friend;
public:
operator _Ty()
{
return _value;
}


protected:
_Ty& operator =(const _Ty &value)
{
_value = value;
return _value;
}
_Ty& operator +=(const _Ty &value)
{
_value += value;
return _value;
}
_Ty& operator -=(const _Ty &value)
{
_value -= value;
return _value;
}
_Ty operator --(int)
{
return _value--;
}
_Ty operator ++(int)
{
return _value++;
}_Ty operator --()
{
return --_value;
}
_Ty operator ++()
{
return ++_value;
}

void* operator =( void *value)
{
_value = value;
return _value;
}
_Ty _value;
};


template<class T> class CNullable
{


public:
Property<CNullable, bool> hasValue;
Property<CNullable, T> Value;
CNullable()
{
hasValue = false;
}
CNullable(T value)
{
hasValue = true;
Value = value;
}
Property<CNullable, T>& operator =(nullptr_t pNull)
{
hasValue = false;
Value = T();
return Value;
}
Property<CNullable, T> & operator =(const T &value)
{
Value = value;
hasValue = true;
return Value;
}
Property<CNullable, T>& operator +=(const T &value)
{
if (hasValue)
{
Value += value;
}
else Value = value;
hasValue = true;
return Value;
}
Property<CNullable, T> & operator -=(const T &value)
{
if (hasValue)
{
Value -= value;
}
else {
Value = -value;
hasValue = true;
}
return Value;
}
CNullable< T>& operator ++(int)
{
CNullable< T> *t = this;
if (hasValue)
{
Value++;
}
else {
Value = 1;


}
return t;
}
CNullable< T>& operator --(int)
{
CNullable< T> t = Value;
if (hasValue)
{
Value--;


}
else {


Value = -1;


}
return t;
}
CNullable<T> & operator ++()
{
if (hasValue)
{
++Value;
}
else {
Value = 1;
}
return this;
}
CNullable<T> & operator --()
{
if (hasValue)
{
--Value;
}
else {
Value = -1;
}
return this;
}
 
T operator&() const
{
return Value;
}
T operator->() const
{
return &Value;
}
bool operator ==(const T &value)
{
return hasValue && Value == value;
}
bool operator !=(const T &value)
{
return hasValue && Value != value;
}
bool operator >(const T &value)
{
return hasValue && Value > value;
}
bool operator >(CNullable<T> &value)
{
return hasValue && value.hasValue && Value > value.Value;
}
bool operator <(const T &value)
{
return hasValue && Value < value;
}
bool operator >=(const T &value)
{
return hasValue && Value >= value;
}
bool operator <=(const T &value)
{
return hasValue && Value <= value;
}


};




以下



template <typename T>

class Nullable final
{
public:
Nullable();
Nullable(const T &value);
Nullable(nullptr_t nullpointer);
const Nullable<T> & operator=(const Nullable<T> &value);
const Nullable<T> & operator=(const T &value);
const Nullable<T> & operator=(nullptr_t nullpointer);
bool HasValue();


public:
class NullableValue final
{
public:
friend class Nullable;


private:
NullableValue();
NullableValue(const T &value);


public:
NullableValue & operator=(const NullableValue &) = delete;
operator const T &() const;
const T * operator&() const;


// https://stackoverflow.com/questions/42183631/inability-to-overload-dot-operator-in-c
T * operator->();


public:
template <typename T2>
friend bool operator==(const Nullable<T2> &op1, const Nullable<T2> &op2);


template <typename T2>
friend bool operator==(const Nullable<T2> &op, const T2 &value);


template <typename T2>
friend bool operator==(const T2 &value, const Nullable<T2> &op);


template <typename T2>
friend bool operator==(const Nullable<T2> &op, nullptr_t nullpointer);


template <typename T2>
friend bool operator!=(const Nullable<T2> &op1, const Nullable<T2> &op2);


template <typename T2>
friend bool operator!=(const Nullable<T2> &op, const T2 &value);


template <typename T2>
friend bool operator!=(const T2 &value, const Nullable<T2> &op);


template <typename T2>
friend bool operator==(nullptr_t nullpointer, const Nullable<T2> &op);


template <typename T2>
friend bool operator!=(const Nullable<T2> &op, nullptr_t nullpointer);


template <typename T2>
friend bool operator!=(nullptr_t nullpointer, const Nullable<T2> &op);


private:
bool m_hasValue;
T m_value;
};


public:
NullableValue Value;
};


template <typename T>
Nullable<T>::NullableValue::NullableValue()
: m_hasValue(false), m_value(T()) { }


template <typename T>
Nullable<T>::NullableValue::NullableValue(const T &value)
: m_hasValue(true), m_value(value) { }


template <typename T>
Nullable<T>::NullableValue::operator const T &() const
{
if (!m_hasValue)
throw std::exception("Nullable object must have a value");


return m_value;
}


template <typename T>
const T * Nullable<T>::NullableValue::operator&() const
{
if (!m_hasValue)
throw std::exception("Nullable object must have a value");


return &m_value;
}


template <typename T>
T * Nullable<T>::NullableValue::operator->()
{
if (!m_hasValue)
throw std::exception("Nullable object must have a value");


return &m_value;
}


template <typename T>
bool Nullable<T>::HasValue() { return Value.m_hasValue; }


template <typename T>
Nullable<T>::Nullable() { }


template <typename T>
Nullable<T>::Nullable(nullptr_t nullpointer) { (void)nullpointer; }


template <typename T>
Nullable<T>::Nullable(const T &value)
: Value(value) { }


template <typename T2>
bool operator==(const Nullable<T2> &op1, const Nullable<T2> &op2)
{
if (op1.Value.m_hasValue != op2.Value.m_hasValue)
return false;


if (op1.Value.m_hasValue)
return op1.Value.m_value == op2.Value.m_value;
else
return true;
}


template <typename T2>
bool operator==(const Nullable<T2> &op, const T2 &value)
{
if (!op.Value.m_hasValue)
return false;


return op.Value.m_value == value;
}


template <typename T2>
bool operator==(const T2 &value, const Nullable<T2> &op)
{
if (!op.Value.m_hasValue)
return false;


return op.Value.m_value == value;
}


template <typename T2>
bool operator==(const Nullable<T2> &op, nullptr_t nullpointer)
{
(void)nullpointer;
return !op.Value.m_hasValue;
}


template <typename T2>
bool operator==(nullptr_t nullpointer, const Nullable<T2> &op)
{
(void)nullpointer;
return !op.Value.m_hasValue;
}


template <typename T2>
bool operator!=(const Nullable<T2> &op1, const Nullable<T2> &op2)
{
if (op1.Value.m_hasValue != op2.Value.m_hasValue)
return true;


if (op1.Value.m_hasValue)
return op1.Value.m_value != op2.Value.m_value;
else
return false;
}


template <typename T2>
bool operator!=(const Nullable<T2> &op, const T2 &value)
{
if (!op.Value.m_hasValue)
return true;


return op.Value.m_value != value;
}


template <typename T2>
bool operator!=(const T2 &value, const Nullable<T2> &op)
{
if (!op.Value.true)
return false;


return op.Value.m_value != value;
}


template <typename T2>
bool operator!=(const Nullable<T2> &op, nullptr_t nullpointer)
{
(void)nullpointer;
return op.Value.m_hasValue;
}


template <typename T2>
bool operator!=(nullptr_t nullpointer, const Nullable<T2> &op)
{
(void)nullpointer;
return op.Value.m_hasValue;
}


template <typename T>
const Nullable<T> & Nullable<T>::operator=(const Nullable<T> &value)
{
Value.m_hasValue = value.Value.m_hasValue;
Value.m_value = value.Value.m_value;
return *this;
}


template <typename T>
const Nullable<T> & Nullable<T>::operator=(const T &value)
{
Value.m_hasValue = true;
Value.m_value = value;
return *this;
}


template <typename T>
const Nullable<T> & Nullable<T>::operator=(nullptr_t nullpointer)
{
(void)nullpointer;
Value.m_hasValue = false;
Value.m_value = T();
return *this;
}
原创粉丝点击