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_OUT_VALUE_POLICY_HPP_INCLUDED
25 #define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED
27 #include <luabind/config.hpp>
28 #include <luabind/detail/policy.hpp>
29 #include <boost/mpl/apply_wrap.hpp>
31 namespace luabind
{ namespace detail
39 #if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 )
42 char_array
<sizeof(U
)> indirect_sizeof_test(by_reference
<U
>);
45 char_array
<sizeof(U
)> indirect_sizeof_test(by_const_reference
<U
>);
48 char_array
<sizeof(U
)> indirect_sizeof_test(by_pointer
<U
>);
51 char_array
<sizeof(U
)> indirect_sizeof_test(by_const_pointer
<U
>);
54 char_array
<sizeof(U
)> indirect_sizeof_test(by_value
<U
>);
59 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_reference
<U
>);
62 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_const_reference
<U
>);
65 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_pointer
<U
>);
68 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_const_pointer
<U
>);
71 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_value
<U
>);
76 struct indirect_sizeof
78 BOOST_STATIC_CONSTANT(int, value
= sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T
))));
81 namespace mpl
= boost::mpl
;
83 template<int Size
, class Policies
= detail::null_type
>
84 struct out_value_converter
87 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
89 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
90 typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
91 new (m_storage
) T(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), index
));
92 return *reinterpret_cast<T
*>(m_storage
);
96 static int match(lua_State
* L
, by_reference
<T
>, int index
)
98 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
99 typedef typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
100 return converter::match(L
, LUABIND_DECORATE_TYPE(T
), index
);
104 void converter_postcall(lua_State
* L
, by_reference
<T
>, int)
106 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
107 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
108 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
109 reinterpret_cast<T
*>(m_storage
)->~T();
113 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
115 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
116 typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
117 new (m_storage
) T(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), index
));
118 return reinterpret_cast<T
*>(m_storage
);
122 static int match(lua_State
* L
, by_pointer
<T
>, int index
)
124 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
125 typedef typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
126 return converter::match(L
, LUABIND_DECORATE_TYPE(T
), index
);
130 void converter_postcall(lua_State
* L
, by_pointer
<T
>, int)
132 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
133 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
134 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
135 reinterpret_cast<T
*>(m_storage
)->~T();
138 char m_storage
[Size
];
141 template<int N
, class Policies
= detail::null_type
>
142 struct out_value_policy
: conversion_policy
<N
>
144 static void precall(lua_State
*, const index_map
&) {}
145 static void postcall(lua_State
*, const index_map
&) {}
147 struct only_accepts_nonconst_references_or_pointers
{};
148 struct can_only_convert_from_lua_to_cpp
{};
150 template<class T
, class Direction
>
153 typedef typename
boost::mpl::if_
<boost::is_same
<lua_to_cpp
, Direction
>
154 , typename
boost::mpl::if_
<boost::mpl::or_
<is_nonconst_reference
<T
>, is_nonconst_pointer
<T
> >
155 , out_value_converter
<indirect_sizeof
<T
>::value
, Policies
>
156 , only_accepts_nonconst_references_or_pointers
158 , can_only_convert_from_lua_to_cpp
163 template<int Size
, class Policies
= detail::null_type
>
164 struct pure_out_value_converter
167 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
170 return *reinterpret_cast<T
*>(m_storage
);
174 static int match(lua_State
* L
, by_reference
<T
>, int index
)
180 void converter_postcall(lua_State
* L
, by_reference
<T
>, int)
182 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
183 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
184 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
185 reinterpret_cast<T
*>(m_storage
)->~T();
189 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
192 return reinterpret_cast<T
*>(m_storage
);
196 static int match(lua_State
* L
, by_pointer
<T
>, int index
)
202 void converter_postcall(lua_State
* L
, by_pointer
<T
>, int)
204 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
205 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
206 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
207 reinterpret_cast<T
*>(m_storage
)->~T();
211 char m_storage
[Size
];
214 template<int N
, class Policies
= detail::null_type
>
215 struct pure_out_value_policy
: conversion_policy
<N
, false>
217 static void precall(lua_State
*, const index_map
&) {}
218 static void postcall(lua_State
*, const index_map
&) {}
220 struct only_accepts_nonconst_references_or_pointers
{};
221 struct can_only_convert_from_lua_to_cpp
{};
223 template<class T
, class Direction
>
226 typedef typename
boost::mpl::if_
<boost::is_same
<lua_to_cpp
, Direction
>
227 , typename
boost::mpl::if_
<boost::mpl::or_
<is_nonconst_reference
<T
>, is_nonconst_pointer
<T
> >
228 , pure_out_value_converter
<indirect_sizeof
<T
>::value
, Policies
>
229 , only_accepts_nonconst_references_or_pointers
231 , can_only_convert_from_lua_to_cpp
241 detail::policy_cons
<detail::out_value_policy
<N
>, detail::null_type
>
242 out_value(LUABIND_PLACEHOLDER_ARG(N
))
244 return detail::policy_cons
<detail::out_value_policy
<N
>, detail::null_type
>();
247 template<int N
, class Policies
>
248 detail::policy_cons
<detail::out_value_policy
<N
, Policies
>, detail::null_type
>
249 out_value(LUABIND_PLACEHOLDER_ARG(N
), const Policies
&)
251 return detail::policy_cons
<detail::out_value_policy
<N
, Policies
>, detail::null_type
>();
255 detail::policy_cons
<detail::pure_out_value_policy
<N
>, detail::null_type
>
256 pure_out_value(LUABIND_PLACEHOLDER_ARG(N
))
258 return detail::policy_cons
<detail::pure_out_value_policy
<N
>, detail::null_type
>();
261 template<int N
, class Policies
>
262 detail::policy_cons
<detail::pure_out_value_policy
<N
, Policies
>, detail::null_type
>
263 pure_out_value(LUABIND_PLACEHOLDER_ARG(N
), const Policies
&)
265 return detail::policy_cons
<detail::pure_out_value_policy
<N
, Policies
>, detail::null_type
>();
269 #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED