any.h
Go to the documentation of this file.00001 #ifndef CPPTL_ANY_H_INCLUDED
00002 # define CPPTL_ANY_H_INCLUDED
00003
00004
00005 # include <typeinfo>
00006 # include <cpptl/typeinfo.h>
00007 # include <string>
00008
00009 namespace CppTL {
00010
00011
00012 class AnyBadCast : public std::bad_cast
00013 {
00014 public:
00015 const char * what() const throw()
00016 {
00017 return "AnyBadCast: "
00018 "Any can not be converted to the specified type.";
00019 }
00020 };
00021
00022
00024 namespace Impl {
00025 class AnyHolder
00026 {
00027 public:
00028 virtual ~AnyHolder() {}
00029
00030 virtual TypeId type() const = 0;
00031
00032 virtual AnyHolder *clone() const = 0;
00033
00034 virtual void *pointer() = 0;
00035 };
00036
00037
00038 template<class AnyType>
00039 class AnyHolderImpl : public AnyHolder
00040 {
00041 public:
00042 AnyHolderImpl( const AnyType &value )
00043 : value_( value )
00044 {
00045 }
00046
00047 const AnyType &value() const
00048 {
00049 return value_;
00050 }
00051
00052 public:
00053 TypeId type() const
00054 {
00055 return typeId( Type<AnyType>() );
00056 }
00057
00058 void *pointer()
00059 {
00060 return &value_;
00061 }
00062
00063 AnyHolder *clone() const
00064 {
00065 return new AnyHolderImpl<AnyType>( value_ );
00066 }
00067
00068 private:
00069 AnyType value_;
00070 };
00071
00072 }
00074
00075
00076 class Any
00077 {
00078 public:
00079 Any();
00080 Any( char value );
00081 Any( bool value );
00082 Any( short value );
00083 Any( int value );
00084 Any( long value );
00085 Any( unsigned short value );
00086 Any( unsigned int value );
00087 Any( unsigned long value );
00088 Any( float value );
00089 Any( double value );
00090 Any( long double value );
00091 Any( const std::string &value );
00092 #if !defined(CPPTL_NO_STD_WSTRING)
00093 Any( const std::wstring &value );
00094 #endif
00095 Any( const Any &other );
00096
00097 Any &operator =( const Any &other );
00098
00099 TypeId type() const;
00100
00101 void swap( Any &other );
00102
00103 bool hasSameType( const Any &other ) const;
00104
00105 bool isEmpty() const;
00106
00107 const void *valuePointer() const;
00108
00109 void *valuePointer();
00110
00111 void copyValueTo( void *storage );
00112
00113
00114 Any( Impl::AnyHolder *holder );
00115
00116 Impl::AnyHolder *holder_;
00117 };
00118
00119
00120 template<class ValueType>
00121 Any makeAny( const ValueType &newValue )
00122 {
00123 return Any( new Impl::AnyHolderImpl<ValueType>( newValue ) );
00124 }
00125
00126
00127
00128
00129
00130 inline Any::Any()
00131 : holder_( 0 )
00132 {
00133 }
00134
00135 inline Any::Any( bool value )
00136 : holder_( new Impl::AnyHolderImpl<bool>( value ) )
00137 {
00138 }
00139
00140 inline Any::Any( char value )
00141 : holder_( new Impl::AnyHolderImpl<char>( value ) )
00142 {
00143 }
00144
00145 inline Any::Any( short value )
00146 : holder_( new Impl::AnyHolderImpl<short>( value ) )
00147 {
00148 }
00149
00150 inline Any::Any( int value )
00151 : holder_( new Impl::AnyHolderImpl<int>( value ) )
00152 {
00153 }
00154
00155 inline Any::Any( long value )
00156 : holder_( new Impl::AnyHolderImpl<long>( value ) )
00157 {
00158 }
00159
00160 inline Any::Any( unsigned short value )
00161 : holder_( new Impl::AnyHolderImpl<unsigned short>( value ) )
00162 {
00163 }
00164
00165 inline Any::Any( unsigned int value )
00166 : holder_( new Impl::AnyHolderImpl<unsigned int>( value ) )
00167 {
00168 }
00169
00170 inline Any::Any( unsigned long value )
00171 : holder_( new Impl::AnyHolderImpl<unsigned long>( value ) )
00172 {
00173 }
00174
00175 inline Any::Any( float value )
00176 : holder_( new Impl::AnyHolderImpl<float>( value ) )
00177 {
00178 }
00179
00180 inline Any::Any( double value )
00181 : holder_( new Impl::AnyHolderImpl<double>( value ) )
00182 {
00183 }
00184
00185 inline Any::Any( long double value )
00186 : holder_( new Impl::AnyHolderImpl<long double>( value ) )
00187 {
00188 }
00189
00190 inline Any::Any( const std::string &value )
00191 : holder_( new Impl::AnyHolderImpl<std::string>( value ) )
00192 {
00193 }
00194
00195 #if !defined(CPPTL_NO_STD_WSTRING)
00196 inline Any::Any( const std::wstring &value )
00197 : holder_( new Impl::AnyHolderImpl<std::wstring>( value ) )
00198 {
00199 }
00200 #endif
00201
00202
00203 inline Any::Any( const Any &other )
00204 : holder_( other.holder_ ? other.holder_->clone() : 0 )
00205 {
00206 }
00207
00208 inline Any &
00209 Any::operator =( const Any &other )
00210 {
00211 Any tmp( other );
00212 swap( tmp );
00213 return *this;
00214 }
00215
00216 inline TypeId
00217 Any::type() const
00218 {
00219 return holder_ ? holder_->type() : typeId( Type<void>() );
00220 }
00221
00222 inline void
00223 Any::swap( Any &other )
00224 {
00225 Impl::AnyHolder *tmp = holder_;
00226 holder_ = other.holder_;
00227 other.holder_ = tmp;
00228 }
00229
00230 inline bool
00231 Any::hasSameType( const Any &other ) const
00232 {
00233 return type() == other.type();
00234 }
00235
00236 inline bool
00237 Any::isEmpty() const
00238 {
00239 return holder_ == 0;
00240 }
00241
00242 inline Any::Any( Impl::AnyHolder *holder )
00243 : holder_( holder )
00244 {
00245 }
00246
00247 inline const void *
00248 Any::valuePointer() const
00249 {
00250
00251 Impl::AnyHolder *holder = const_cast<Impl::AnyHolder *>( holder_ );
00252 return holder ? holder->pointer() : 0;
00253 }
00254
00255 inline void *
00256 Any::valuePointer()
00257 {
00258 return holder_ ? holder_->pointer() : 0;
00259 }
00260
00261
00262 }
00263
00264
00265
00266
00267
00268
00269 template<class ValueType>
00270 CppTL::Any &set( CppTL::Any &value,
00271 const ValueType &newValue )
00272 {
00273 value = CppTL::Any( new CppTL::Impl::AnyHolderImpl<ValueType>( newValue ) );
00274 return value;
00275 }
00276
00277 template<class ValueType>
00278 const ValueType &any_cast( const CppTL::Any &value, CppTL::Type<ValueType> )
00279 {
00280 if ( value.type() != CppTL::typeId( CppTL::Type<ValueType>() ) )
00281 throw CppTL::AnyBadCast();
00282
00283 return static_cast<CppTL::Impl::AnyHolderImpl<ValueType> *>( value.holder_ )->value();
00284 }
00285
00286 template<class ValueType>
00287 const ValueType *get( const CppTL::Any *value, CppTL::Type<ValueType> )
00288 {
00289 if ( value->type() != CppTL::typeId( CppTL::Type<ValueType>() ) )
00290 return 0;
00291 return &( static_cast<CppTL::Impl::AnyHolderImpl<ValueType> *>( value->holder_ )->value() );
00292 }
00293
00294
00295 #endif // CPPTL_ANY_H_INCLUDED