#pragma once
#ifndef __HWINNULLABLE_H__
#define __HWINNULLABLE_H__
#include "hwinException.h"
#ifdef _MANAGED
#pragma managed(push,off)
#endif
#pragma pack(push,8)
namespace harlinn
{
namespace windows
{
template<typename T>
class Nullable
{
public:
typedef T value_type;
private:
bool hasValue_;
T value_;
public:
Nullable( )
: hasValue_( false ),
value_( value_type( ) )
{
}
explicit Nullable( const value_type& theValue )
: hasValue_( true ),
value_( theValue )
{
}
Nullable( const Nullable& theOther )
: hasValue_( theOther.hasValue_ ),
value_( theOther.value_ )
{
}
Nullable( Nullable&& theOther )
: hasValue_( theOther.hasValue_ ),
value_( std::move( theOther.value_ ) )
{
}
Nullable& operator = ( const Nullable& theOther )
{
value_ = theOther.value_;
hasValue_ = theOther.hasValue_;
return *this;
}
Nullable& operator = ( Nullable&& theOther )
{
value_ = std::move( theOther.value_ );
hasValue_ = theOther.hasValue_;
return *this;
}
Nullable& operator = ( const value_type& theValue )
{
value_ = theValue;
hasValue_ = true;
return *this;
}
Nullable& operator = ( nullptr_t )
{
value_ = T( );
hasValue_ = false;
return *this;
}
explicit operator bool( ) const
{
if ( hasValue_ )
{
value_ ? true : false;
}
return false;
}
bool HasValue( ) const
{
return hasValue_;
}
const value_type& Value( ) const
{
if ( !hasValue_ )
{
throw InvalidOperationException( "Value not set" );
}
return value_;
}
value_type Value( )
{
if ( !hasValue_ )
{
throw InvalidOperationException( "Value not set" );
}
return value_;
}
Nullable& SetValue( const value_type& theValue )
{
value_ = theValue;
hasValue_ = true;
return *this;
}
Nullable& SetValue( nullptr_t )
{
value_ = T( );
hasValue_ = false;
return *this;
}
};
template<typename T>
bool operator == ( const Nullable<T>& first, nullptr_t )
{
return first.HasValue( ) == false;
}
template<typename T>
bool operator == ( nullptr_t, const Nullable<T>& second )
{
return second.HasValue( ) == false;
}
template<typename T>
bool operator != ( const Nullable<T>& first, nullptr_t )
{
return first.HasValue( );
}
template<typename T>
bool operator != ( nullptr_t, const Nullable<T>& second )
{
return second.HasValue( );
}
}
}
#pragma pack(pop)
#ifdef _MANAGED
#pragma managed(pop)
#endif
#endif