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
00009 namespace Typelib
00010 {
00020 class Value
00021 {
00022 void* m_data;
00023 boost::reference_wrapper<Type const> m_type;
00024
00025 public:
00026 Value()
00027 : m_data(0), m_type(Registry::null()) {}
00028
00029 Value(void* data, Type const& type)
00030 : m_data(data), m_type(type) {}
00031
00033 void* getData() const { return m_data; }
00035 Type const& getType() const { return m_type; }
00036
00037 bool operator == (Value const& with) const
00038 { return (m_data == with.m_data) && (m_type.get() == with.m_type.get()); }
00039 bool operator != (Value const& with) const
00040 { return (m_data != with.m_data) || (m_type.get() != with.m_type.get()); }
00041 };
00042
00045 class ValueVisitor
00046 {
00047 class TypeDispatch;
00048 friend class TypeDispatch;
00049 bool m_defval;
00050
00051 TypeDispatch* m_dispatcher;
00052
00053 protected:
00054 virtual bool visit_ (int8_t &) { return m_defval; }
00055 virtual bool visit_ (uint8_t &) { return m_defval; }
00056 virtual bool visit_ (int16_t &) { return m_defval; }
00057 virtual bool visit_ (uint16_t&) { return m_defval; }
00058 virtual bool visit_ (int32_t &) { return m_defval; }
00059 virtual bool visit_ (uint32_t&) { return m_defval; }
00060 virtual bool visit_ (int64_t &) { return m_defval; }
00061 virtual bool visit_ (uint64_t&) { return m_defval; }
00062 virtual bool visit_ (float &) { return m_defval; }
00063 virtual bool visit_ (double &) { return m_defval; }
00064
00065 virtual bool visit_ (Value const& v, OpaqueType const& t);
00066 virtual bool visit_ (Value const& v, Pointer const& t);
00067 virtual bool visit_ (Value const& v, Array const& a);
00068 virtual bool visit_ (Value const& v, Container const& a);
00069 virtual bool visit_ (Value const& v, Compound const& c);
00070 virtual bool visit_ (Value const& v, Compound const& c, Field const& f);
00071 virtual bool visit_ (Enum::integral_type& v, Enum const& e);
00072
00073 public:
00074 ValueVisitor(bool defval = false);
00075 virtual ~ValueVisitor();
00076
00078 virtual void dispatch(Value v);
00079
00080 void apply(Value v);
00081 };
00082
00085 class BadValueCast : public std::exception {};
00086
00088 class FieldNotFound : public BadValueCast
00089 {
00090 public:
00091 ~FieldNotFound() throw() {}
00092 std::string const name;
00093 FieldNotFound(std::string const& name_)
00094 : name(name_) {}
00095 };
00096
00099 class FieldGetter : public ValueVisitor
00100 {
00101 std::string m_name;
00102 Value m_field;
00103
00104 using ValueVisitor::visit_;
00105
00106 bool visit_(Compound const& type) { return true; }
00107 bool visit_(Value const& value, Compound const&, Field const& field)
00108 {
00109 if (field.getName() == m_name)
00110 {
00111 m_field = value;
00112 return false;
00113 }
00114 return true;
00115 }
00116
00117 public:
00118 FieldGetter()
00119 : ValueVisitor(true) {}
00120 Value apply(Value v, std::string const& name)
00121 {
00122 m_name = name;
00123 m_field = Value();
00124 ValueVisitor::apply(v);
00125 if (! m_field.getData())
00126 throw FieldNotFound(name);
00127 return m_field;
00128 }
00129
00130 };
00131
00134 inline Value value_get_field(Value v, std::string const& name)
00135 {
00136 FieldGetter getter;
00137 return getter.apply(v, name);
00138 }
00139
00142 inline Value value_get_field(void* ptr, Type const& type, std::string const& name)
00143 {
00144 Value v(ptr, type);
00145 return value_get_field(v, name);
00146 }
00147 }
00148
00149 #endif
00150