Changeset 14887 for lang/cplusplus/reflection
- Timestamp:
- 06/30/08 07:41:07 (5 years ago)
- Location:
- lang/cplusplus/reflection/trunk
- Files:
-
- 2 modified
-
reflection.hpp (modified) (4 diffs)
-
test.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
lang/cplusplus/reflection/trunk/reflection.hpp
r14745 r14887 3 3 4 4 #include <map> 5 #include <stdexcept> 5 6 #include <string> 6 7 #include <typeinfo> … … 12 13 virtual ~member() {} 13 14 virtual char T::*ptr() const = 0; 14 virtual void set(T *, const void *, const std::type_info &) const = 0;15 virtual void set(T &, const void *, const std::type_info &) const = 0; 15 16 template <typename Vt> Vt T::*ptr(Vt*) const { 16 17 return reinterpret_cast<Vt T::*>(ptr()); 17 18 } 18 template <typename Vt> Vt get( T *obj) const {19 return mem_rebuild<Vt>(&(obj ->*ptr()), this);19 template <typename Vt> Vt get(const T &obj) const { 20 return mem_rebuild<Vt>(&(obj.*ptr()), this); 20 21 } 21 template <typename Vt> void set(T *obj, const Vt &v) const {22 template <typename Vt> void set(T &obj, const Vt &v) const { 22 23 set(obj, &v, typeid(Vt)); 23 24 } … … 33 34 return reinterpret_cast<char T::*>(p); 34 35 } 35 virtual void set(T *obj, const void *s, const std::type_info &t) const {36 obj ->*p = mem_rebuild<Vt>(s, t);36 virtual void set(T &obj, const void *s, const std::type_info &t) const { 37 obj.*p = mem_rebuild<Vt>(s, t); 37 38 } 38 39 }; 39 40 40 template <class T, class C = typename T::reflection_definition> struct base 41 template <class T> struct def { 42 /* 43 * Specialize this template deriving from def_base to define a reflection 44 * table. For example: 45 * 46 * struct def<std::pair<int, int> > : def_base<std::pair<int, int> > { 47 * def() { 48 * REFLECTION(first); 49 * REFLECTION(second); 50 * } 51 * }; 52 */ 53 private: 54 def(); // intentionally made private to require specialization 55 }; 56 57 template <class T> struct def_base 41 58 : public std::map<std::string, member<T>*> { 42 59 typedef T Klass; 43 static Cmap;60 static def<T> map; 44 61 template <typename Vt> 45 62 void register_(const std::string &name, Vt T::*p) { … … 48 65 }; 49 66 50 template <class T, class C> C base<T, C>::map; 51 52 template <class T, typename Vt> 53 bool get(const T& obj, const std::string &n, Vt* v) { 54 typename T::reflection_definition::const_iterator i 55 = T::reflection_definition::map.find(n); 56 if (i == T::reflection_definition::map.end() 57 || ! i->second->type_is(typeid(*v))) 58 return false; 59 *v = obj.*i->second->ptr((Vt*)NULL); 60 return true; 67 template <class T> def<T> def_base<T>::map; 68 69 struct member_not_found_error : public std::domain_error { 70 std::string _name; 71 member_not_found_error(const std::string& n) 72 : std::domain_error("member not found"), _name(n) {} 73 ~member_not_found_error() throw() {} 74 std::string name() const { 75 return _name; 76 } 77 }; 78 79 template <typename Vt, class T> 80 Vt get(const T &obj, const std::string &n) { 81 typename def<T>::const_iterator i = def<T>::map.find(n); 82 if (i == def<T>::map.end()) 83 throw member_not_found_error(n); 84 return i->second->get<Vt>(obj); 61 85 } 62 86 63 87 template <class T, typename Vt> 64 bool set(T& obj, const std::string &n, const Vt& v) { 65 typename T::reflection_definition::const_iterator i = 66 T::reflection_definition::map.find(n); 67 if (i == T::reflection_definition::map.end() 68 || ! i->second->type_is(typeid(v))) 69 return false; 70 obj.*i->second->ptr((Vt*)NULL) = v; 71 return true; 88 void set(T &obj, const std::string &n, const Vt &v) { 89 typename def<T>::const_iterator i = def<T>::map.find(n); 90 if (i == def<T>::map.end()) 91 throw member_not_found_error(n); 92 i->second->set(obj, v); 72 93 } 73 94 -
lang/cplusplus/reflection/trunk/test.cpp
r14745 r14887 8 8 int i; 9 9 string s; 10 Foo() : i(), s() {} 11 12 struct reflection_definition : public reflection::base<Foo> { 13 reflection_definition() { 10 }; 11 12 namespace reflection { 13 template <> struct def<Foo> : public def_base<Foo> { 14 def() { 14 15 REFLECTION(i); 15 16 REFLECTION(s); … … 24 25 f.i = 3; 25 26 int i = 0; 26 i = Foo::reflection_definition::map["i"]->get<int>(&f);27 Foo::reflection_definition::map["i"]->set(&f, lexical_cast<string>(i + 1));28 Foo::reflection_definition::map["s"]->set(&f, string("hello world!"));27 i = reflection::get<int>(f, "i"); 28 reflection::set(f, "i", lexical_cast<string>(i + 1)); 29 reflection::set(f, "s", string("hello world!")); 29 30 30 for ( Foo::reflection_definition::const_iterator i31 = Foo::reflection_definition::map.begin();32 i != Foo::reflection_definition::map.end();31 for (reflection::def<Foo>::const_iterator i 32 = reflection::def<Foo>::map.begin(); 33 i != reflection::def<Foo>::map.end(); 33 34 ++i) 34 cout << i->first << " = " << i->second->get<std::string>( &f) << endl;35 cout << i->first << " = " << i->second->get<std::string>(f) << endl; 35 36 36 37 return 0;
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)