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