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>
30 namespace luabind
{ namespace detail
38 #if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 )
41 char_array
<sizeof(U
)> indirect_sizeof_test(by_reference
<U
>);
44 char_array
<sizeof(U
)> indirect_sizeof_test(by_const_reference
<U
>);
47 char_array
<sizeof(U
)> indirect_sizeof_test(by_pointer
<U
>);
50 char_array
<sizeof(U
)> indirect_sizeof_test(by_const_pointer
<U
>);
53 char_array
<sizeof(U
)> indirect_sizeof_test(by_value
<U
>);
58 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_reference
<U
>);
61 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_const_reference
<U
>);
64 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_pointer
<U
>);
67 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_const_pointer
<U
>);
70 char_array
<sizeof(typename identity
<U
>::type
)> indirect_sizeof_test(by_value
<U
>);
75 struct indirect_sizeof
77 BOOST_STATIC_CONSTANT(int, value
= sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T
))));
80 template<int Size
, class Policies
= detail::null_type
>
81 struct out_value_converter
84 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
86 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
87 typename
converter_policy::template generate_converter
<T
, lua_to_cpp
>::type converter
;
88 new (m_storage
) T(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), index
));
89 return *reinterpret_cast<T
*>(m_storage
);
93 static int match(lua_State
* L
, by_reference
<T
>, int index
)
95 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
96 typedef typename
converter_policy::template generate_converter
<T
, lua_to_cpp
>::type converter
;
97 return converter::match(L
, LUABIND_DECORATE_TYPE(T
), index
);
101 void converter_postcall(lua_State
* L
, by_reference
<T
>, int)
103 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
104 typename
converter_policy::template generate_converter
<T
, cpp_to_lua
>::type converter
;
105 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
106 reinterpret_cast<T
*>(m_storage
)->~T();
110 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
112 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
113 typename
converter_policy::template generate_converter
<T
, lua_to_cpp
>::type converter
;
114 new (m_storage
) T(converter
.apply(L
, LUABIND_DECORATE_TYPE(T
), index
));
115 return reinterpret_cast<T
*>(m_storage
);
119 static int match(lua_State
* L
, by_pointer
<T
>, int index
)
121 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
122 typedef typename
converter_policy::template generate_converter
<T
, lua_to_cpp
>::type converter
;
123 return converter::match(L
, LUABIND_DECORATE_TYPE(T
), index
);
127 void converter_postcall(lua_State
* L
, by_pointer
<T
>, int)
129 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
130 typename
converter_policy::template generate_converter
<T
, cpp_to_lua
>::type converter
;
131 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
132 reinterpret_cast<T
*>(m_storage
)->~T();
135 char m_storage
[Size
];
138 template<int N
, class Policies
= detail::null_type
>
139 struct out_value_policy
: conversion_policy
<N
>
141 static void precall(lua_State
*, const index_map
&) {}
142 static void postcall(lua_State
*, const index_map
&) {}
144 struct only_accepts_nonconst_references_or_pointers
{};
145 struct can_only_convert_from_lua_to_cpp
{};
147 template<class T
, class Direction
>
148 struct generate_converter
150 typedef typename
boost::mpl::if_
<boost::is_same
<lua_to_cpp
, Direction
>
151 , typename
boost::mpl::if_
<boost::mpl::or_
<is_nonconst_reference
<T
>, is_nonconst_pointer
<T
> >
152 , out_value_converter
<indirect_sizeof
<T
>::value
, Policies
>
153 , only_accepts_nonconst_references_or_pointers
155 , can_only_convert_from_lua_to_cpp
160 template<int Size
, class Policies
= detail::null_type
>
161 struct pure_out_value_converter
164 T
& apply(lua_State
* L
, by_reference
<T
>, int index
)
167 return *reinterpret_cast<T
*>(m_storage
);
171 static int match(lua_State
* L
, by_reference
<T
>, int index
)
177 void converter_postcall(lua_State
* L
, by_reference
<T
>, int)
179 typedef typename find_conversion_policy
<1, Policies
>::type converter_policy
;
180 typename
converter_policy::template generate_converter
<T
, cpp_to_lua
>::type converter
;
181 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
182 reinterpret_cast<T
*>(m_storage
)->~T();
186 T
* apply(lua_State
* L
, by_pointer
<T
>, int index
)
189 return reinterpret_cast<T
*>(m_storage
);
193 static int match(lua_State
* L
, by_pointer
<T
>, int index
)
199 void converter_postcall(lua_State
* L
, by_pointer
<T
>, int)
201 typedef typename find_conversion_policy
<2, Policies
>::type converter_policy
;
202 typename
converter_policy::template generate_converter
<T
, cpp_to_lua
>::type converter
;
203 converter
.apply(L
, *reinterpret_cast<T
*>(m_storage
));
204 reinterpret_cast<T
*>(m_storage
)->~T();
208 char m_storage
[Size
];
211 template<int N
, class Policies
= detail::null_type
>
212 struct pure_out_value_policy
: conversion_policy
<N
, false>
214 static void precall(lua_State
*, const index_map
&) {}
215 static void postcall(lua_State
*, const index_map
&) {}
217 struct only_accepts_nonconst_references_or_pointers
{};
218 struct can_only_convert_from_lua_to_cpp
{};
220 template<class T
, class Direction
>
221 struct generate_converter
223 typedef typename
boost::mpl::if_
<boost::is_same
<lua_to_cpp
, Direction
>
224 , typename
boost::mpl::if_
<boost::mpl::or_
<is_nonconst_reference
<T
>, is_nonconst_pointer
<T
> >
225 , pure_out_value_converter
<indirect_sizeof
<T
>::value
, Policies
>
226 , only_accepts_nonconst_references_or_pointers
228 , can_only_convert_from_lua_to_cpp
238 detail::policy_cons
<detail::out_value_policy
<N
>, detail::null_type
>
239 out_value(boost::arg
<N
>) { return detail::policy_cons
<detail::out_value_policy
<N
>, detail::null_type
>(); }
241 template<int N
, class Policies
>
242 detail::policy_cons
<detail::out_value_policy
<N
, Policies
>, detail::null_type
>
243 out_value(boost::arg
<N
>, const Policies
&) { return detail::policy_cons
<detail::out_value_policy
<N
, Policies
>, detail::null_type
>(); }
246 detail::policy_cons
<detail::pure_out_value_policy
<N
>, detail::null_type
>
247 pure_out_value(boost::arg
<N
>) { return detail::policy_cons
<detail::pure_out_value_policy
<N
>, detail::null_type
>(); }
249 template<int N
, class Policies
>
250 detail::policy_cons
<detail::pure_out_value_policy
<N
, Policies
>, detail::null_type
>
251 pure_out_value(boost::arg
<N
>, const Policies
&) { return detail::policy_cons
<detail::pure_out_value_policy
<N
, Policies
>, detail::null_type
>(); }
254 #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED