$search
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