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
86 int const consumed_args(...)
92 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
94 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
95 typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
96 new (m_storage
) T(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), index
));
97 return *reinterpret_cast<T
*>(m_storage
);
101 static int match(lua_State
* L
, by_reference
<T
>, int index
)
103 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
104 typedef typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
105 return converter::match(L
, LUABIND_DECORATE_TYPE(T
), index
);
109 void converter_postcall(lua_State
* L
, by_reference
<T
>, int)
111 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
112 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
113 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
114 reinterpret_cast<T
*>(m_storage
)->~T();
118 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
120 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
121 typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
122 new (m_storage
) T(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), index
));
123 return reinterpret_cast<T
*>(m_storage
);
127 static int match(lua_State
* L
, by_pointer
<T
>, int index
)
129 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
130 typedef typename
mpl::apply_wrap2
<converter_policy
,T
,lua_to_cpp
>::type converter
;
131 return converter::match(L
, LUABIND_DECORATE_TYPE(T
), index
);
135 void converter_postcall(lua_State
* L
, by_pointer
<T
>, int)
137 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
138 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
139 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
140 reinterpret_cast<T
*>(m_storage
)->~T();
143 char m_storage
[Size
];
146 template<int N
, class Policies
= detail::null_type
>
147 struct out_value_policy
: conversion_policy
<N
>
149 static void precall(lua_State
*, const index_map
&) {}
150 static void postcall(lua_State
*, const index_map
&) {}
152 struct only_accepts_nonconst_references_or_pointers
{};
153 struct can_only_convert_from_lua_to_cpp
{};
155 template<class T
, class Direction
>
158 typedef typename
boost::mpl::if_
<boost::is_same
<lua_to_cpp
, Direction
>
159 , typename
boost::mpl::if_
<boost::mpl::or_
<is_nonconst_reference
<T
>, is_nonconst_pointer
<T
> >
160 , out_value_converter
<indirect_sizeof
<T
>::value
, Policies
>
161 , only_accepts_nonconst_references_or_pointers
163 , can_only_convert_from_lua_to_cpp
168 template<int Size
, class Policies
= detail::null_type
>
169 struct pure_out_value_converter
171 int const consumed_args(...)
177 T
& apply(lua_State
*, by_reference
<T
>, int)
180 return *reinterpret_cast<T
*>(m_storage
);
184 static int match(lua_State
*, by_reference
<T
>, int)
190 void converter_postcall(lua_State
* L
, by_reference
<T
>, int)
192 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
193 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
194 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
195 reinterpret_cast<T
*>(m_storage
)->~T();
199 T
* apply(lua_State
*, by_pointer
<T
>, int)
202 return reinterpret_cast<T
*>(m_storage
);
206 static int match(lua_State
*, by_pointer
<T
>, int)
212 void converter_postcall(lua_State
* L
, by_pointer
<T
>, int)
214 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
215 typename
mpl::apply_wrap2
<converter_policy
,T
,cpp_to_lua
>::type converter
;
216 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
217 reinterpret_cast<T
*>(m_storage
)->~T();
221 char m_storage
[Size
];
224 template<int N
, class Policies
= detail::null_type
>
225 struct pure_out_value_policy
: conversion_policy
<N
, false>
227 static void precall(lua_State
*, const index_map
&) {}
228 static void postcall(lua_State
*, const index_map
&) {}
230 struct only_accepts_nonconst_references_or_pointers
{};
231 struct can_only_convert_from_lua_to_cpp
{};
233 template<class T
, class Direction
>
236 typedef typename
boost::mpl::if_
<boost::is_same
<lua_to_cpp
, Direction
>
237 , typename
boost::mpl::if_
<boost::mpl::or_
<is_nonconst_reference
<T
>, is_nonconst_pointer
<T
> >
238 , pure_out_value_converter
<indirect_sizeof
<T
>::value
, Policies
>
239 , only_accepts_nonconst_references_or_pointers
241 , can_only_convert_from_lua_to_cpp
251 detail::policy_cons
<detail::out_value_policy
<N
>, detail::null_type
>
252 out_value(LUABIND_PLACEHOLDER_ARG(N
))
254 return detail::policy_cons
<detail::out_value_policy
<N
>, detail::null_type
>();
257 template<int N
, class Policies
>
258 detail::policy_cons
<detail::out_value_policy
<N
, Policies
>, detail::null_type
>
259 out_value(LUABIND_PLACEHOLDER_ARG(N
), const Policies
&)
261 return detail::policy_cons
<detail::out_value_policy
<N
, Policies
>, detail::null_type
>();
265 detail::policy_cons
<detail::pure_out_value_policy
<N
>, detail::null_type
>
266 pure_out_value(LUABIND_PLACEHOLDER_ARG(N
))
268 return detail::policy_cons
<detail::pure_out_value_policy
<N
>, detail::null_type
>();
271 template<int N
, class Policies
>
272 detail::policy_cons
<detail::pure_out_value_policy
<N
, Policies
>, detail::null_type
>
273 pure_out_value(LUABIND_PLACEHOLDER_ARG(N
), const Policies
&)
275 return detail::policy_cons
<detail::pure_out_value_policy
<N
, Policies
>, detail::null_type
>();
279 #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED