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)
5 #ifndef LUABIND_INHERITANCE_090217_HPP
6 # define LUABIND_INHERITANCE_090217_HPP
13 # include <luabind/typeid.hpp>
15 namespace luabind
{ namespace detail
{
17 typedef void*(*cast_function
)(void*);
18 typedef std::size_t class_id
;
20 class_id
const unknown_class
= std::numeric_limits
<class_id
>::max();
24 class LUABIND_API cast_graph
30 // `src` and `p` here describe the *most derived* object. This means that
31 // for a polymorphic type, the pointer must be cast with
32 // dynamic_cast<void*> before being passed in here, and `src` has to
34 std::pair
<void*, std::size_t> cast(
35 void* p
, class_id src
, class_id target
36 , class_id dynamic_id
, void const* dynamic_ptr
) const;
37 void insert(class_id src
, class_id target
, cast_function cast
);
41 std::auto_ptr
<impl
> m_impl
;
44 // Maps a type_id to a class_id. Note that this..
48 class_id
get(type_id
const& type
) const;
49 class_id
get_local(type_id
const& type
);
50 void put(class_id id
, type_id
const& type
);
53 typedef std::map
<type_id
, class_id
> map_type
;
57 inline class_id
class_id_map::get(type_id
const& type
) const
59 map_type::const_iterator i
= m_classes
.find(type
);
60 if (i
== m_classes
.end() || i
->second
> unknown_class
/ 2)
65 inline class_id
class_id_map::get_local(type_id
const& type
)
67 std::pair
<map_type::iterator
, bool> result
= m_classes
.insert(
68 std::make_pair(type
, 0));
71 result
.first
->second
= unknown_class
- m_classes
.size();
73 return result
.first
->second
;
76 inline void class_id_map::put(class_id id
, type_id
const& type
)
78 std::pair
<map_type::iterator
, bool> result
= m_classes
.insert(
79 std::make_pair(type
, id
));
80 assert(result
.second
|| result
.first
->second
== id
);
87 class_rep
* get(class_id id
) const;
88 void put(class_id id
, class_rep
* cls
);
91 std::vector
<class_rep
*> m_classes
;
94 inline class_rep
* class_map::get(class_id id
) const
96 if (id
>= m_classes
.size())
101 inline void class_map::put(class_id id
, class_rep
* cls
)
103 if (id
>= m_classes
.size())
104 m_classes
.resize(id
+ 1);
108 template <class S
, class T
>
111 static void* execute(void* p
)
113 return static_cast<T
*>(static_cast<S
*>(p
));
117 template <class S
, class T
>
120 static void* execute(void* p
)
122 return dynamic_cast<T
*>(static_cast<S
*>(p
));
126 // Thread safe class_id allocation.
127 LUABIND_API class_id
allocate_class_id();
130 struct registered_class
132 static class_id
const id
;
136 class_id
const registered_class
<T
>::id
= allocate_class_id();
139 struct registered_class
<T
const>
140 : registered_class
<T
>
143 }} // namespace luabind::detail
145 #endif // LUABIND_INHERITANCE_090217_HPP