value.hh

Go to the documentation of this file.
00001 #ifndef TYPELIB_VALUE_HH
00002 #define TYPELIB_VALUE_HH
00003 
00004 #include "typemodel.hh"
00005 #include "typevisitor.hh"
00006 #include "registry.hh"
00007 #include <boost/ref.hpp>
00008 #include <boost/mpl/if.hpp>
00009 #include <boost/mpl/bool.hpp>
00010 #include <limits>
00011 #include "normalized_numerics.hh"
00012 
00013 namespace Typelib
00014 {
00024     class Value
00025     {
00026         void*       m_data;
00027         boost::reference_wrapper<Type const> m_type;
00028         
00029     public:
00030         Value()
00031             : m_data(0), m_type(Registry::null()) {}
00032 
00033         Value(void* data, Type const& type)
00034             : m_data(data), m_type(type) {}
00035 
00037         void* getData() const { return m_data; }
00039         Type const& getType() const { return m_type; }
00040 
00041         bool operator == (Value const& with) const
00042         { return (m_data == with.m_data) && (m_type.get() == with.m_type.get()); }
00043         bool operator != (Value const& with) const
00044         { return (m_data != with.m_data) || (m_type.get() != with.m_type.get()); }
00045     };
00046 
00049     class ValueVisitor
00050     {
00051         class TypeDispatch;
00052         friend class TypeDispatch;
00053         bool m_defval;
00054 
00055         TypeDispatch* m_dispatcher;
00056 
00057     protected:
00058         virtual bool visit_ (int8_t  &) { return m_defval; }
00059         virtual bool visit_ (uint8_t &) { return m_defval; }
00060         virtual bool visit_ (int16_t &) { return m_defval; }
00061         virtual bool visit_ (uint16_t&) { return m_defval; }
00062         virtual bool visit_ (int32_t &) { return m_defval; }
00063         virtual bool visit_ (uint32_t&) { return m_defval; }
00064         virtual bool visit_ (int64_t &) { return m_defval; }
00065         virtual bool visit_ (uint64_t&) { return m_defval; }
00066         virtual bool visit_ (float   &) { return m_defval; }
00067         virtual bool visit_ (double  &) { return m_defval; }
00068 
00069         virtual bool visit_ (Value const& v, OpaqueType const& t);
00070         virtual bool visit_ (Value const& v, Pointer const& t);
00071         virtual bool visit_ (Value const& v, Array const& a);
00072         virtual bool visit_ (Value const& v, Container const& a);
00073         virtual bool visit_ (Value const& v, Compound const& c); 
00074         virtual bool visit_ (Value const& v, Compound const& c, Field const& f);
00075         virtual bool visit_ (Enum::integral_type& v, Enum const& e);
00076 
00077     public:
00078         ValueVisitor(bool defval = false) 
00079             : m_defval(defval), m_dispatcher(0) {}
00080         virtual ~ValueVisitor() {}
00081 
00083         virtual void dispatch(Value v);
00084 
00085         void apply(Value v);
00086     };
00087 
00090     class BadValueCast : public std::exception {};
00091 
00096     template<typename T>
00097     class CastingVisitor : public ValueVisitor
00098     {
00099         bool m_found;
00100         T    m_value;
00101 
00102         bool visit_( typename normalized_numeric_type<T>::type& v)
00103         {
00104             m_value = v;
00105             m_found = true;
00106             return false;
00107         }
00108          
00109     public:
00110         CastingVisitor()
00111             : ValueVisitor(false), m_found(false), m_value() {};
00112         T& apply(Value v)
00113         {
00114             m_found = false;
00115             ValueVisitor::apply(v);
00116             if (!m_found)
00117                 throw BadValueCast();
00118 
00119             return m_value;
00120         }
00121     };
00122 
00125     template<typename T>
00126     T& value_cast(Value v)
00127     {
00128         CastingVisitor<T> caster;
00129         return caster.apply(v);
00130     }
00131 
00134     template<typename T>
00135     T& value_cast(void* ptr, Type const& type)
00136     { return value_cast<T>(Value(ptr, type)); }
00137 
00139     class FieldNotFound : public BadValueCast 
00140     {
00141     public:
00142         ~FieldNotFound() throw() {}
00143         std::string const name;
00144         FieldNotFound(std::string const& name_)
00145             : name(name_) {}
00146     };
00147 
00150     class FieldGetter : public ValueVisitor
00151     {
00152         std::string m_name;
00153         Value m_field;
00154 
00155         bool visit_(Compound const& type) { return true; }
00156         bool visit_(Value const& value, Compound const&, Field const& field)
00157         {
00158             if (field.getName() == m_name)
00159             {
00160                 m_field = value;
00161                 return false;
00162             }
00163             return true;
00164         }
00165         
00166     public:
00167         FieldGetter()
00168             : ValueVisitor(true) {}
00169         Value apply(Value v, std::string const& name)
00170         {
00171             m_name = name;
00172             m_field = Value();
00173             ValueVisitor::apply(v);
00174             if (! m_field.getData())
00175                 throw FieldNotFound(name);
00176             return m_field;
00177         }
00178         
00179     };
00180 
00183     inline Value value_get_field(Value v, std::string const& name)
00184     {
00185         FieldGetter getter;
00186         return getter.apply(v, name);
00187     }
00188 
00191     inline Value value_get_field(void* ptr, Type const& type, std::string const& name)
00192     {
00193         Value v(ptr, type);
00194         return value_get_field(v, name);
00195     }
00196 }
00197 
00198 #endif
00199 

Generated on Thu Jan 22 16:37:20 2009 for typeLib by doxygen 1.5.6
SourceForge.net Project Page