#ifndef NULLABLE_H
#define NULLABLE_H
#include "odbclib.h"
namespace odbclib
{
template<typename T>
class Nullable
{
typedef T const& const_reference;
typedef T const* const_pointer;
public:
Nullable()
:m_value(T()),
m_isNull(true)
{
}
Nullable(T const& value)
:m_value(value)
{
}
bool isNull() const{return m_isNull;}
operator T()throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
operator T()const throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
Nullable& operator=(Nullable const& value)
{
if(value.isNull())
m_isNull = true;
return *this;
}
Nullable& operator=(T const& value)
{
m_value = value;
m_isNull = false;
return *this;
}
T const& value()const throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
T& value()throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
public:
static Nullable const& Null;
private:
T m_value;
bool m_isNull;
template<typename V>
friend ostream& operator<<(ostream&,Nullable<V> const&) throw(runtime_error);
template<typename V>
friend istream& operator>>(istream&,Nullable<V> &);
};
template<typename T>
Nullable<T> const& Nullable<T>::Null = Nullable<T>();
template<typename T>
ostream& operator<<(ostream& os,Nullable<T> const& value) throw(runtime_error)
{
if(value.m_isNull)
throw runtime_error("null has no value");
os << value.m_value;
return os;
}
template<typename T>
istream& operator>>(istream& is,Nullable<T> &value)
{
is >> value.m_value;
return is;
}
template<>
class Nullable<string>
{
public:
Nullable()
:m_value(string()),
m_isNull(true)
{
}
Nullable(string const& value)
:m_value(value),
m_isNull(false)
{
}
Nullable(char const* value)
:m_value(value),
m_isNull(false)
{
}
Nullable(Nullable const& other)
{
m_value = other.m_value;
m_isNull = other.m_isNull;
}
template<size_t N>
Nullable(char const (&a)[N])
:m_value(a),
m_isNull(false)
{
}
bool isNull() const{return m_isNull;}
operator string()throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
operator string()const throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
Nullable& operator=(char const* value)
{
m_value.assign(value);
m_isNull = false;
return *this;
}
string const& value()const throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
string& value()throw(runtime_error)
{
if(isNull())
throw runtime_error("null has no value");
return m_value;
}
public:
static Nullable const& Null;
private:
string m_value;
bool m_isNull;
template<typename V>
friend ostream& operator<<(ostream&,Nullable<V> const&) throw(runtime_error);
template<typename V>
friend istream& operator>>(istream&,Nullable<V> &);
};
}
#endif
#include "odbclib.h"
namespace odbclib
{
Nullable<string> const& Nullable<string>::Null = Nullable<string>();
}