- Main Page
- Related Pages
- Classes
- Files

# _value.h

Go to the documentation of this file.

    00001 /* ========================================================================
    00002 ** Extended Template and Library
    00003 ** Abstraction for a Generic Value Type
    00004 ** $Id$
    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: //constructor 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: //constructor 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