My Project
inheritance.hpp
1 // Copyright Daniel Wallin 2009. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 
5 #ifndef LUABIND_INHERITANCE_090217_HPP
6 # define LUABIND_INHERITANCE_090217_HPP
7 
8 # include <cassert>
9 # include <limits>
10 # include <map>
11 # include <memory>
12 # include <vector>
13 # include <luabind/typeid.hpp>
14 # include <boost/scoped_ptr.hpp>
15 
16 namespace luabind { namespace detail {
17 
18 typedef void*(*cast_function)(void*);
19 typedef std::size_t class_id;
20 
21 class_id const unknown_class = (std::numeric_limits<class_id>::max)();
22 
23 class class_rep;
24 
25 class LUABIND_API cast_graph
26 {
27 public:
28  cast_graph();
29  ~cast_graph();
30 
31  // `src` and `p` here describe the *most derived* object. This means that
32  // for a polymorphic type, the pointer must be cast with
33  // dynamic_cast<void*> before being passed in here, and `src` has to
34  // match typeid(*p).
35  std::pair<void*, int> cast(
36  void* p, class_id src, class_id target
37  , class_id dynamic_id, void const* dynamic_ptr) const;
38  void insert(class_id src, class_id target, cast_function cast);
39 
40 private:
41  class impl;
42  boost::scoped_ptr<impl> m_impl;
43 };
44 
45 // Maps a type_id to a class_id. Note that this actually partitions the
46 // id-space into two, using one half for "local" ids; ids that are used only as
47 // keys into the conversion cache. This is needed because we need a unique key
48 // even for types that hasn't been registered explicitly.
49 class LUABIND_API class_id_map
50 {
51 public:
52  class_id_map();
53 
54  class_id get(type_id const& type) const;
55  class_id get_local(type_id const& type);
56  void put(class_id id, type_id const& type);
57 
58 private:
59  typedef std::map<type_id, class_id> map_type;
60  map_type m_classes;
61  class_id m_local_id;
62 
63  static class_id const local_id_base;
64 };
65 
66 inline class_id_map::class_id_map()
67  : m_local_id(local_id_base)
68 {}
69 
70 inline class_id class_id_map::get(type_id const& type) const
71 {
72  map_type::const_iterator i = m_classes.find(type);
73  if (i == m_classes.end() || i->second >= local_id_base)
74  return unknown_class;
75  return i->second;
76 }
77 
78 inline class_id class_id_map::get_local(type_id const& type)
79 {
80  std::pair<map_type::iterator, bool> result = m_classes.insert(
81  std::make_pair(type, 0));
82 
83  if (result.second)
84  result.first->second = m_local_id++;
85 
86  assert(m_local_id >= local_id_base);
87 
88  return result.first->second;
89 }
90 
91 inline void class_id_map::put(class_id id, type_id const& type)
92 {
93  assert(id < local_id_base);
94 
95  std::pair<map_type::iterator, bool> result = m_classes.insert(
96  std::make_pair(type, 0));
97 
98  assert(
99  result.second
100  || result.first->second == id
101  || result.first->second >= local_id_base
102  );
103 
104  result.first->second = id;
105 }
106 
108 {
109 public:
110  class_rep* get(class_id id) const;
111  void put(class_id id, class_rep* cls);
112 
113 private:
114  std::vector<class_rep*> m_classes;
115 };
116 
117 inline class_rep* class_map::get(class_id id) const
118 {
119  if (id >= m_classes.size())
120  return 0;
121  return m_classes[id];
122 }
123 
124 inline void class_map::put(class_id id, class_rep* cls)
125 {
126  if (id >= m_classes.size())
127  m_classes.resize(id + 1);
128  m_classes[id] = cls;
129 }
130 
131 template <class S, class T>
133 {
134  static void* execute(void* p)
135  {
136  return static_cast<T*>(static_cast<S*>(p));
137  }
138 };
139 
140 template <class S, class T>
142 {
143  static void* execute(void* p)
144  {
145  return dynamic_cast<T*>(static_cast<S*>(p));
146  }
147 };
148 
149 // Thread safe class_id allocation.
150 LUABIND_API class_id allocate_class_id(type_id const& cls);
151 
152 template <class T>
154 {
155  static class_id const id;
156 };
157 
158 template <class T>
159 class_id const registered_class<T>::id = allocate_class_id(typeid(T));
160 
161 template <class T>
162 struct registered_class<T const>
163  : registered_class<T>
164 {};
165 
166 }} // namespace luabind::detail
167 
168 #endif // LUABIND_INHERITANCE_090217_HPP
Definition: inheritance.hpp:141
Definition: typeid.hpp:22
Definition: inheritance.hpp:49
Definition: inheritance.hpp:132
Definition: inheritance.hpp:153
Definition: inheritance.cpp:108
Definition: PEtypes.h:507
Definition: inheritance.hpp:25
Definition: class_rep.hpp:68
Definition: inheritance.hpp:107