Fix bug when passing type with holder by value to Lua.
[luabind.git] / luabind / detail / decorate_type.hpp
blobbb144c463bb4d0cf2dcba5a4e5bf0a5005252f18
1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
24 #ifndef LUABIND_DECORATE_TYPE_HPP_INCLUDED
25 #define LUABIND_DECORATE_TYPE_HPP_INCLUDED
27 #include <luabind/config.hpp>
28 #include <luabind/detail/primitives.hpp>
30 namespace luabind { namespace detail
33 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
35 template<class T>
36 struct decorated_type
38 static by_value<T> t;
39 static inline by_value<T>& get() { return /*by_value<T>()*/t; }
42 template<class T>
43 by_value<T> decorated_type<T>::t;
45 template<class T>
46 struct decorated_type<T*>
48 static by_pointer<T> t;
49 static inline by_pointer<T>& get() { return /*by_pointer<T>()*/t; }
52 template<class T>
53 by_pointer<T> decorated_type<T*>::t;
55 template<class T>
56 struct decorated_type<const T*>
58 static by_const_pointer<T> t;
59 static inline by_const_pointer<T> get() { return /*by_const_pointer<T>()*/t; }
62 template<class T>
63 by_const_pointer<T> decorated_type<const T*>::t;
65 template<class T>
66 struct decorated_type<const T* const>
68 static by_const_pointer<T> t;
69 static inline by_const_pointer<T>& get() { return /*by_const_pointer<T>()*/t; }
72 template<class T>
73 by_const_pointer<T> decorated_type<const T* const>::t;
75 template<class T>
76 struct decorated_type<T&>
78 static by_reference<T> t;
79 static inline by_reference<T>& get() { return /*by_reference<T>()*/t; }
82 template<class T>
83 by_reference<T> decorated_type<T&>::t;
85 template<class T>
86 struct decorated_type<const T&>
88 static by_const_reference<T> t;
89 static inline by_const_reference<T>& get() { return /*by_const_reference<T>()*/t; }
92 template<class T>
93 by_const_reference<T> decorated_type<const T&>::t;
95 #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get()
97 #else
99 #include <boost/type_traits/is_array.hpp>
101 namespace
103 LUABIND_ANONYMOUS_FIX char decorated_type_array[64];
106 template<class T>
107 struct decorated_type_cref_impl
109 #if defined(BOOST_MSVC) && BOOST_MSVC == 1200
110 template<class U>
111 static by_const_reference<U> get(const U&)
113 return by_const_reference<U>();
115 static T data() { return reinterpret_cast<T>(decorated_type_array); }
116 #else
118 static void(*data())(T)
119 { return (void(*)(T))0; }
121 template<class U>
122 static by_const_reference<U> get(void(*f)(const U&))
123 { return by_const_reference<U>(); }
124 #endif
127 template<class T>
128 struct decorated_type_ref_impl
130 #if defined(BOOST_MSVC) && BOOST_MSVC == 1200
131 template<class U>
132 static by_reference<U> get(U&)
134 return by_reference<U>();
136 static T data() { return reinterpret_cast<T>(decorated_type_array); }
137 #else
138 static void(*data())(T)
139 { return (void(*)(T))0; }
141 template<class U>
142 static by_reference<U> get(void(*)(U&))
143 { return by_reference<U>(); }
144 #endif
147 template<class T>
148 struct decorated_type_cptr_impl
150 #if defined(BOOST_MSVC) && BOOST_MSVC == 1200
151 template<class U>
152 static by_const_pointer<U> get(const U*)
154 return by_const_pointer<U>();
156 static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
157 #else
158 static void(*data())(T)
159 { return (void(*)(T))0; }
161 template<class U>
162 static by_const_pointer<U> get(void(*)(const U*))
163 { return by_const_pointer<U>(); }
164 #endif
167 template<class T>
168 struct decorated_type_ptr_impl
170 #if defined(BOOST_MSVC) && BOOST_MSVC == 1200
171 template<class U>
172 static by_pointer<U> get(U*)
174 return by_pointer<U>();
176 static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
177 #else
178 static void(*data())(T)
179 { return (void(*)(T))0; }
181 template<class U>
182 static by_pointer<U> get(void(*)(U*))
183 { return by_pointer<U>(); }
184 #endif
187 template<class T>
188 struct decorated_type_value_impl
190 #if defined(BOOST_MSVC) && BOOST_MSVC == 1200
191 template<class U>
192 static by_value<U> get(U&)
194 return by_value<U>();
196 static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
197 #else
198 static void(*data())(T&)
199 { return (void(*)(T&))0; }
201 template<class U>
202 static by_value<U> get(void(*)(U&))
203 { return by_value<U>(); }
204 #endif
207 template<>
208 struct decorated_type_value_impl<void>
210 static by_value<void> get(int)
212 return by_value<void>();
214 static int data() { return 0; }
217 template<class T>
218 struct decorated_type_array_impl
220 template<class U>
221 static by_pointer<U> get(U*)
223 return by_pointer<U>();
226 template<class U>
227 static by_pointer<U> get(void(*)(U))
228 { return by_pointer<U>(); }
230 static T& data() { return reinterpret_cast<T&>(decorated_type_array); }
233 template<class T>
234 struct decorated_type
235 // : boost::mpl::if_<boost::is_array<T>
236 // , decorated_type_array_impl<T>
237 : boost::mpl::if_<luabind::detail::is_const_reference<T>
238 , decorated_type_cref_impl<T>
239 , typename boost::mpl::if_<luabind::detail::is_nonconst_reference<T>
240 , decorated_type_ref_impl<T>
241 , typename boost::mpl::if_<luabind::detail::is_nonconst_pointer<T>
242 , decorated_type_ptr_impl<T>
243 , typename boost::mpl::if_<luabind::detail::is_const_pointer<T>
244 , decorated_type_cptr_impl<T>
245 , decorated_type_value_impl<T>
246 >::type
247 >::type
248 >::type
249 >::type
250 // >::type
254 #if defined(BOOST_MSVC) && BOOST_MSVC == 1200
255 #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(luabind::detail::decorated_type<t>::data())
256 #else
257 // #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get((void(*)(type<t>))0)
258 #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(luabind::detail::decorated_type<t>::data())
259 //#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type<t>::get(type<t>())
260 #endif
262 #endif
266 #endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED