00001
00002 #ifndef d_Variant_h
00003 #define d_Variant_h 1
00004
00005 #include <iostream>
00006
00007 #include "oLibrary.h"
00008
00009
00010 class _ODLL d_Variant
00011 {
00012 public :
00013 d_Variant() : data(0) {}
00014
00015 d_Variant( const d_Variant & rhs )
00016 {
00017 if( rhs.data )
00018 rhs.data->AddRef();
00019 data = rhs.data;
00020 }
00021
00022 ~d_Variant()
00023 {
00024 if( data )
00025 data->Release();
00026 }
00027
00028
00029
00030 d_Variant& operator = ( const d_Variant& rhs )
00031 {
00032 if( rhs.data )
00033 rhs.data->AddRef();
00034 if( data )
00035 data->Release();
00036 data = rhs.data;
00037 return *this;
00038 }
00039
00040
00041
00042 template<typename T> d_Variant ( T v )
00043 : data ( new Impl<T>(v) )
00044 { data->AddRef() ; }
00045
00046
00047
00048
00049
00050
00051 template<typename T> operator T () const
00052 { return CastFromBase<T>( data )->data ; }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template<typename T> const T& get() const
00063 { return CastFromBase<T>( data )->data ; }
00064
00065 char* raw() const;
00066
00067
00068
00069
00070
00071
00072 template<typename T> bool is_type() const
00073 { return typeid(*data)==typeid(Impl<T>); }
00074
00075
00076
00077
00078
00079
00080
00081 template<typename T> bool is_type(T v) const
00082 { return typeid(*data)==typeid(v); }
00083
00084 private :
00085
00086
00087
00088
00089 struct ImplBase
00090 {
00091 ImplBase() : refs ( 0 ) {}
00092 virtual ~ImplBase() {}
00093 void AddRef () { refs ++ ; }
00094 void Release() { refs -- ;
00095 if ( refs == 0 )
00096 delete this ;
00097 }
00098 size_t refs ;
00099 } ;
00100
00101
00102
00103
00104
00105 template<typename T>
00106 struct Impl : ImplBase
00107 {
00108 Impl ( T v ) : data ( v ) {}
00109 ~Impl () {}
00110 T data ;
00111 } ;
00112
00113
00114
00115 template<typename T>
00116 static ImplBase* CastToBase ( Impl<T>* v )
00117 { return v ; }
00118
00119 template<typename T>
00120 static Impl<T>* CastFromBase ( ImplBase* v )
00121 {
00122
00123
00124 Impl<T>* p = dynamic_cast<Impl<T>*> ( v ) ;
00125 if ( p == 0 )
00126 throw invalid_argument
00127 ( typeid(T).name()+string(" is not a valid type"));
00128 return p ;
00129 }
00130
00131 ImplBase* data;
00132 };
00133
00134
00135 #endif
00136
00137