Initial C++0x support.
[luabind.git] / luabind / detail / constructor.hpp
blobd8d5460f6af0903b62ebc66042ea539e81522181
1 // Copyright Daniel Wallin 2008. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #if !BOOST_PP_IS_ITERATING
7 # ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
8 # define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
10 # include <luabind/get_main_thread.hpp>
11 # include <luabind/object.hpp>
12 # include <luabind/wrapper_base.hpp>
13 # include <luabind/detail/inheritance.hpp>
15 # ifndef LUABIND_CPP0x
16 # include <boost/preprocessor/iteration/iterate.hpp>
17 # include <boost/preprocessor/iteration/local.hpp>
18 # include <boost/preprocessor/repetition/enum_params.hpp>
19 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
20 # endif
22 namespace luabind { namespace detail {
24 inline void inject_backref(lua_State*, void*, void*)
27 template <class T>
28 void inject_backref(lua_State* L, T* p, wrap_base*)
30 weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p));
33 # ifdef LUABIND_CPP0x
35 template <class T, class Pointer, class Signature>
36 struct construct;
38 template <class T, class Pointer, class R, class Self, class... Args>
39 struct construct<T, Pointer, vector<R, Self, Args...> >
41 typedef pointer_holder<Pointer, T> holder_type;
43 void operator()(argument const& self_, Args... args) const
45 object_rep* self = touserdata<object_rep>(self_);
47 std::auto_ptr<T> instance(new T(args...));
48 inject_backref(self_.interpreter(), instance.get(), instance.get());
50 void* naked_ptr = instance.get();
51 Pointer ptr(instance.release());
53 void* storage = self->allocate(sizeof(holder_type));
55 self->set_instance(new (storage) holder_type(
56 ptr, registered_class<T>::id, naked_ptr));
60 # else // LUABIND_CPP0x
62 template <std::size_t Arity, class T, class Pointer, class Signature>
63 struct construct_aux;
65 template <class T, class Pointer, class Signature>
66 struct construct
67 : construct_aux<mpl::size<Signature>::value - 2, T, Pointer, Signature>
68 {};
70 template <class T, class Pointer, class Signature>
71 struct construct_aux<0, T, Pointer, Signature>
73 typedef pointer_holder<Pointer, T> holder_type;
75 void operator()(argument const& self_) const
77 object_rep* self = touserdata<object_rep>(self_);
79 std::auto_ptr<T> instance(new T);
80 inject_backref(self_.interpreter(), instance.get(), instance.get());
82 void* naked_ptr = instance.get();
83 Pointer ptr(instance.release());
85 void* storage = self->allocate(sizeof(holder_type));
87 self->set_instance(new (storage) holder_type(
88 ptr, registered_class<T>::id, naked_ptr));
92 # define BOOST_PP_ITERATION_PARAMS_1 \
93 (3, (1, LUABIND_MAX_ARITY, <luabind/detail/constructor.hpp>))
94 # include BOOST_PP_ITERATE()
96 # endif // LUABIND_CPP0x
98 }} // namespace luabind::detail
100 # endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP
102 #else // !BOOST_PP_IS_ITERATING
104 # define N BOOST_PP_ITERATION()
106 template <class T, class Pointer, class Signature>
107 struct construct_aux<N, T, Pointer, Signature>
109 typedef typename mpl::begin<Signature>::type first;
110 typedef typename mpl::next<first>::type iter0;
112 # define BOOST_PP_LOCAL_MACRO(n) \
113 typedef typename mpl::next< \
114 BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \
115 typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n));
117 # define BOOST_PP_LOCAL_LIMITS (1,N)
118 # include BOOST_PP_LOCAL_ITERATE()
120 typedef pointer_holder<Pointer, T> holder_type;
122 void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const
124 object_rep* self = touserdata<object_rep>(self_);
126 std::auto_ptr<T> instance(new T(BOOST_PP_ENUM_PARAMS(N,_)));
127 inject_backref(self_.interpreter(), instance.get(), instance.get());
129 void* naked_ptr = instance.get();
130 Pointer ptr(instance.release());
132 void* storage = self->allocate(sizeof(holder_type));
134 self->set_instance(new (storage) holder_type(
135 ptr, registered_class<T>::id, naked_ptr));
139 # undef N
141 #endif