*** empty log message ***
[luabind.git] / luabind / out_value_policy.hpp
blob4bc63a309bc46e69a553aaaaedf82042370385e1
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
32 template<int N>
33 struct char_array
35 char storage[N];
38 #if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 )
40 template<class U>
41 char_array<sizeof(U)> indirect_sizeof_test(by_reference<U>);
43 template<class U>
44 char_array<sizeof(U)> indirect_sizeof_test(by_const_reference<U>);
46 template<class U>
47 char_array<sizeof(U)> indirect_sizeof_test(by_pointer<U>);
49 template<class U>
50 char_array<sizeof(U)> indirect_sizeof_test(by_const_pointer<U>);
52 template<class U>
53 char_array<sizeof(U)> indirect_sizeof_test(by_value<U>);
55 #else
57 template<class U>
58 char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_reference<U>);
60 template<class U>
61 char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_const_reference<U>);
63 template<class U>
64 char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_pointer<U>);
66 template<class U>
67 char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_const_pointer<U>);
69 template<class U>
70 char_array<sizeof(typename identity<U>::type)> indirect_sizeof_test(by_value<U>);
72 #endif
74 template<class T>
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
83 template<class T>
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);
92 template<class T>
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);
100 template<class T>
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();
109 template<class 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);
118 template<class T>
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);
126 template<class T>
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
154 >::type
155 , can_only_convert_from_lua_to_cpp
156 >::type type;
160 template<int Size, class Policies = detail::null_type>
161 struct pure_out_value_converter
163 template<class T>
164 T& apply(lua_State* L, by_reference<T>, int index)
166 new (m_storage) T();
167 return *reinterpret_cast<T*>(m_storage);
170 template<class T>
171 static int match(lua_State* L, by_reference<T>, int index)
173 return 0;
176 template<class T>
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();
185 template<class T>
186 T* apply(lua_State* L, by_pointer<T>, int index)
188 new (m_storage) T();
189 return reinterpret_cast<T*>(m_storage);
192 template<class T>
193 static int match(lua_State* L, by_pointer<T>, int index)
195 return 0;
198 template<class T>
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
227 >::type
228 , can_only_convert_from_lua_to_cpp
229 >::type type;
235 namespace luabind
237 template<int N>
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>(); }
245 template<int N>
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