Changeset 14745

Show
Ignore:
Timestamp:
06/28/08 08:10:39 (5 years ago)
Author:
kazuho
Message:

initial support for automatic type conversion

Location:
lang/cplusplus/reflection/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • lang/cplusplus/reflection/trunk/memrebuild.hpp

    r14744 r14745  
    77namespace mem_rebuild_ns { 
    88   
     9  struct type_is_t { 
     10    virtual ~type_is_t() {} 
     11    virtual bool type_is(const std::type_info &) const = 0; 
     12  }; 
     13   
    914  template <typename T> 
    1015  struct builder { 
     
    1217    virtual ~builder() {} 
    1318    virtual func_t get(const std::type_info &) const = 0; 
     19    virtual func_t get(const type_is_t *) const = 0; 
    1420    virtual bool equals(const std::type_info &) const = 0; 
    1521    virtual bool equals(const builder*) const = 0; 
     
    2127    get(const std::type_info &t) const { 
    2228      if (typeid(Source) != t) 
     29        return NULL; 
     30      return instantiate; 
     31    } 
     32    virtual typename builder<Target>::func_t get(const type_is_t *t) const { 
     33      if (! t->type_is(typeid(Source))) 
    2334        return NULL; 
    2435      return instantiate; 
     
    108119 
    109120#undef MEM_REBUILD_ 
     121 
     122  template <typename T, typename TI> T core(const void *p, TI t) 
     123  { 
     124    typedef mem_rebuild_ns::builder_map<T> map; 
     125    for (typename map::const_iterator i = map::m.begin(); 
     126         i != map::m.end(); 
     127         ++i) { 
     128      typename mem_rebuild_ns::builder<T>::func_t instantiate; 
     129      if ((instantiate = (*i)->get(t)) != NULL) 
     130        return (*instantiate)(p); 
     131    } 
     132    throw std::bad_cast(); 
     133  } 
     134 
    110135}; 
    111136 
    112137template <typename T> T mem_rebuild(const void *p, const std::type_info &t) 
    113138{ 
    114   typedef mem_rebuild_ns::builder_map<T> map; 
    115   for (typename map::const_iterator i = map::m.begin(); 
    116        i != map::m.end(); 
    117        ++i) { 
    118     typename mem_rebuild_ns::builder<T>::func_t instantiate; 
    119     if ((instantiate = (*i)->get(t)) != NULL) 
    120       return (*instantiate)(p); 
    121   } 
    122   throw std::bad_cast(); 
     139  return mem_rebuild_ns::core<T, const std::type_info&>(p, t); 
     140} 
     141 
     142template <typename T> T mem_rebuild(const void *p, 
     143                                    const mem_rebuild_ns::type_is_t *t) 
     144{ 
     145  return mem_rebuild_ns::core<T, const mem_rebuild_ns::type_is_t*>(p, t); 
    123146} 
    124147 
  • lang/cplusplus/reflection/trunk/reflection.hpp

    r14685 r14745  
    55#include <string> 
    66#include <typeinfo> 
     7#include "memrebuild.hpp" 
    78 
    89namespace reflection { 
    910   
    10   struct type_info { 
    11     virtual ~type_info() {} 
    12     virtual type_info* clone() const = 0; 
    13     virtual bool equal(const std::type_info &) const = 0; 
    14   }; 
    15  
    16   bool operator==(const type_info* x, const std::type_info &y) { 
    17     return x->equal(y); 
    18   } 
    19    
    20   bool operator==(const std::type_info &x, const type_info* y) { 
    21     return y == x; 
    22   } 
    23    
    24   bool operator!=(const type_info *x, const std::type_info &y) { 
    25     return ! (x == y); 
    26   } 
    27    
    28   bool operator!=(const std::type_info &x, const type_info* y) { 
    29     return ! (x == y); 
    30   } 
    31    
    32   template <class T> struct type_info_t : public type_info { 
    33     virtual type_info_t *clone() const { return new type_info_t<T>(); } 
    34     virtual bool equal(const std::type_info &x) const { return typeid(T) == x; } 
     11  template <class T> struct member : public mem_rebuild_ns::type_is_t { 
     12    virtual ~member() {} 
     13    virtual char T::*ptr() const = 0; 
     14    virtual void set(T *, const void *, const std::type_info &) const = 0; 
     15    template <typename Vt> Vt T::*ptr(Vt*) const { 
     16      return reinterpret_cast<Vt T::*>(ptr()); 
     17    } 
     18    template <typename Vt> Vt get(T *obj) const { 
     19      return mem_rebuild<Vt>(&(obj->*ptr()), this); 
     20    } 
     21    template <typename Vt> void set(T *obj, const Vt &v) const { 
     22      set(obj, &v, typeid(Vt)); 
     23    } 
    3524  }; 
    3625   
    37   template <class T> struct member { 
    38     char T::*_ptr; 
    39     type_info *type; 
    40     member(char T::*p, const type_info &t) : _ptr(p), type(t.clone()) {} 
    41     member(const member<T>& x) : _ptr(x._ptr), type(x.type->clone()) {} 
    42     ~member() { delete type; } 
    43     member& operator=(const member<T>& x) { 
    44       if (this == &x) return *this; 
    45       _ptr = x._ptr; 
    46       delete type; 
    47       type = x.type->clone(); 
    48       return *this; 
     26  template <class T, typename Vt> struct member_t : public member<T> { 
     27    Vt T::*p; 
     28    member_t(Vt T::*_p) : p(_p) {} 
     29    virtual bool type_is(const std::type_info &x) const { 
     30      return typeid(Vt) == x; 
    4931    } 
    50     template <typename Vt> Vt T::*ptr(Vt*) const { 
    51       return reinterpret_cast<Vt T::*>(_ptr); 
     32    virtual char T::*ptr() const { 
     33      return reinterpret_cast<char T::*>(p); 
     34    } 
     35    virtual void set(T * obj, const void *s, const std::type_info &t) const { 
     36      obj->*p = mem_rebuild<Vt>(s, t); 
    5237    } 
    5338  }; 
    5439   
    5540  template <class T, class C = typename T::reflection_definition> struct base 
    56     : public std::map<std::string, member<T> > { 
     41    : public std::map<std::string, member<T>*> { 
    5742    typedef T Klass; 
    5843    static C map; 
    5944    template <typename Vt> 
    6045    void register_(const std::string &name, Vt T::*p) { 
    61       insert(std::make_pair(name, 
    62                             member<T>(reinterpret_cast<char T::*>(p), 
    63                                       type_info_t<Vt>()))); 
     46      insert(std::pair<std::string, member<T>*>(name, new member_t<T, Vt>(p))); 
    6447    } 
    6548  }; 
     
    7255      = T::reflection_definition::map.find(n); 
    7356    if (i == T::reflection_definition::map.end() 
    74         || typeid(*v) != i->second.type) 
     57        || ! i->second->type_is(typeid(*v))) 
    7558      return false; 
    76     *v = obj.*i->second.ptr((Vt*)NULL); 
     59    *v = obj.*i->second->ptr((Vt*)NULL); 
    7760    return true; 
    7861  } 
     
    8265    typename T::reflection_definition::const_iterator i = 
    8366      T::reflection_definition::map.find(n); 
    84     if (i == T::reflection_definition::map.end() || typeid(v) != i->second.type) 
     67    if (i == T::reflection_definition::map.end() 
     68        || ! i->second->type_is(typeid(v))) 
    8569      return false; 
    86     obj.*i->second.ptr((Vt*)NULL) = v; 
     70    obj.*i->second->ptr((Vt*)NULL) = v; 
    8771    return true; 
    8872  } 
  • lang/cplusplus/reflection/trunk/test.cpp

    r14571 r14745  
    33 
    44using namespace std; 
     5using namespace boost; 
    56 
    67struct Foo { 
     
    2324  f.i = 3; 
    2425  int i = 0; 
    25   reflection::get(f, "i", &i); 
    26   ++i; 
    27   reflection::set(f, "i", i); 
    28   reflection::set(f, "s", string("hello world!")); 
     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!")); 
    2929   
    3030  for (Foo::reflection_definition::const_iterator i 
    3131         = Foo::reflection_definition::map.begin(); 
    3232       i != Foo::reflection_definition::map.end(); 
    33        ++i) { 
    34     cout << i->first << " = "; 
    35     if (i->second.type == typeid(int)) { 
    36       cout << f.*i->second.ptr((int*)NULL); 
    37     } else if (i->second.type == typeid(std::string)) { 
    38       cout << f.*i->second.ptr((std::string*)NULL); 
    39     } 
    40     cout << endl; 
    41   } 
     33       ++i) 
     34    cout << i->first << " = " << i->second->get<std::string>(&f) << endl; 
    4235   
    43   return f.i; 
     36  return 0; 
    4437} 
    4538