_value.h

Go to the documentation of this file.
00001 /* ========================================================================
00002 ** Extended Template and Library
00003 ** Abstraction for a Generic Value Type
00004 ** $Id: _value.h 334 2007-03-16 00:37:48Z dooglus $
00005 **
00006 ** Copyright (c) 2002 Adrian Bentley
00007 **
00008 ** This package is free software; you can redistribute it and/or
00009 ** modify it under the terms of the GNU General Public License as
00010 ** published by the Free Software Foundation; either version 2 of
00011 ** the License, or (at your option) any later version.
00012 **
00013 ** This package is distributed in the hope that it will be useful,
00014 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 ** General Public License for more details.
00017 **
00018 ** === N O T E S ===========================================================
00019 **
00020 ** This is an internal header file, included by other ETL headers.
00021 ** You should not attempt to use it directly.
00022 **
00023 ** ========================================================================= */
00024 
00025 /* === S T A R T =========================================================== */
00026 
00027 #ifndef __ETL_VALUE_H
00028 #define __ETL_VALUE_H
00029 
00030 /* === H E A D E R S ======================================================= */
00031 #include <algorithm>
00032 #include <typeinfo>
00033 #include <cassert>
00034 
00035 /* === M A C R O S ========================================================= */
00036 
00037 /* === T Y P E D E F S ===================================================== */
00038 
00039 /* === C L A S S E S & S T R U C T S ======================================= */
00040 
00050 template < typename T >
00051 class value_store_type
00052 {
00053 public:
00054     typedef T                       value_type;
00055 };
00056 
00057 _ETL_BEGIN_NAMESPACE
00058 
00065 class value
00066 {
00067     struct contentholder
00068     {
00069         virtual ~contentholder() {}
00070         virtual contentholder *clone() const = 0;
00071         virtual const std::type_info &type() const = 0;
00072     };
00073 
00074     contentholder   *content;
00075 
00076 public: //structor interface
00077     value()
00078         :content(0)
00079     {
00080     }
00081 
00082     value(const value &v)
00083         :content( v.content ? v.content->clone() : 0 )
00084     {
00085     }
00086 
00087     /* Copies the object passed to it
00088     */
00089     template < typename T >
00090     value(const T &v)
00091         :content( new holder< typename value_store_type<T>::value_type >
00092                         (reinterpret_cast<const typename value_store_type<T>::value_type &>(v)) )
00093     {
00094     }
00095 
00096 public: //modifier interface
00097 
00098     value & swap(value & rhs)
00099     {
00100         std::swap(content, rhs.content);
00101         return *this;
00102     }
00103 
00104     template<typename ValueType>
00105     value & operator=(const ValueType & rhs)
00106     {
00107         value(rhs).swap(*this);
00108         return *this;
00109     }
00110 
00111     value & operator=(const value & rhs)
00112     {
00113         value(rhs).swap(*this);
00114         return *this;
00115     }
00116 
00117 public: //query interface
00118 
00119     bool empty() const
00120     {
00121         return content == 0;
00122     }
00123 
00124     const std::type_info & type() const
00125     {
00126         return content ? content->type() : typeid(void);
00127     }
00128 
00129 private: //implementation interface
00130 
00131     template < typename T >
00132     class holder : public contentholder
00133     {
00134     public: //representation
00135         T   obj;
00136 
00137     public: //structor interface
00138 
00139         holder(const T &o)
00140             :obj(o)
00141         {
00142         }
00143 
00144         holder(const holder<T> &h)
00145             :obj(h.obj)
00146         {
00147         }
00148 
00149     public: //accessor interface
00150         virtual contentholder *clone() const
00151         {
00152             return new holder(*this);
00153         }
00154 
00155         virtual const std::type_info &type() const
00156         {
00157             return typeid(T);
00158         }
00159 
00160     public: //allocation interface
00161         void *operator new(unsigned int size)
00162         {
00163             assert(size == sizeof(holder<T>));
00164 
00165             //use pool allocation at some point
00166             return malloc(size);
00167         }
00168 
00169         void operator delete(void *p)
00170         {
00171             assert(p);
00172             //use pool allocation at some point
00173             return free(p);
00174         }
00175     };
00176 
00177     template < typename ValueType >
00178     friend ValueType *value_cast(value *v);
00179 };
00180 
00183 class bad_value_cast : public std::bad_cast
00184 {
00185 public:
00186     virtual const char * what() const throw()
00187     {
00188         return "etl::bad_value_cast: " "failed conversion using boost::value_cast";
00189     }
00190 };
00191 
00198 template < typename ValueType >
00199 ValueType *value_cast(value *v)
00200 {
00201     assert(v);
00202 
00203     return ( typeid(typename value_store_type<ValueType>::value_type) == v->type() )
00204             ? &static_cast<value::holder<ValueType> *>(v->content)->obj
00205             : 0;
00206 }
00207 
00211 template < typename ValueType >
00212 const ValueType * value_cast(const value *v)
00213 {
00214     return value_cast<ValueType>(const_cast<value *>(v));
00215 }
00216 
00224 template < typename ValueType >
00225 ValueType value_cast(const value &v)
00226 {
00227     const ValueType * result = value_cast<ValueType>(&v);
00228     if(!result)
00229         throw bad_value_cast();
00230     return *result;
00231 }
00232 
00233 _ETL_END_NAMESPACE
00234 
00235 /* === E N D =============================================================== */
00236 
00237 #endif

Generated on Fri Jun 22 14:48:48 2007 for ETL by  doxygen 1.5.2