CppUnit project page CppUnit home page

any.h

Go to the documentation of this file.
00001 #ifndef CPPTL_ANY_H_INCLUDED
00002 # define CPPTL_ANY_H_INCLUDED
00003 
00004 //# include "ctti.h"
00005 # include <typeinfo>  // std::bad_cast
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: // overridden from AnyHolder
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    } // namespace Impl
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    //private:     // not private for access by get/set/cast function
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    // class Any
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       // this const cast avoid extra virtual function
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 } // namespace CppTL
00263 
00264 
00265 
00266 // Those function are imported in the global namespace since all compiler don't have
00267 // argument dependent look-up. They all take type 'Any' in parameter which is in a namespace.
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

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers