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 : m_defval(defval), m_dispatcher(0) {} 00076 virtual ~ValueVisitor() {} 00077 00079 virtual void dispatch(Value v); 00080 00081 void apply(Value v); 00082 }; 00083 00086 class BadValueCast : public std::exception {}; 00087 00089 class FieldNotFound : public BadValueCast 00090 { 00091 public: 00092 ~FieldNotFound() throw() {} 00093 std::string const name; 00094 FieldNotFound(std::string const& name_) 00095 : name(name_) {} 00096 }; 00097 00100 class FieldGetter : public ValueVisitor 00101 { 00102 std::string m_name; 00103 Value m_field; 00104 00105 bool visit_(Compound const& type) { return true; } 00106 bool visit_(Value const& value, Compound const&, Field const& field) 00107 { 00108 if (field.getName() == m_name) 00109 { 00110 m_field = value; 00111 return false; 00112 } 00113 return true; 00114 } 00115 00116 public: 00117 FieldGetter() 00118 : ValueVisitor(true) {} 00119 Value apply(Value v, std::string const& name) 00120 { 00121 m_name = name; 00122 m_field = Value(); 00123 ValueVisitor::apply(v); 00124 if (! m_field.getData()) 00125 throw FieldNotFound(name); 00126 return m_field; 00127 } 00128 00129 }; 00130 00133 inline Value value_get_field(Value v, std::string const& name) 00134 { 00135 FieldGetter getter; 00136 return getter.apply(v, name); 00137 } 00138 00141 inline Value value_get_field(void* ptr, Type const& type, std::string const& name) 00142 { 00143 Value v(ptr, type); 00144 return value_get_field(v, name); 00145 } 00146 } 00147 00148 #endif 00149