1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
2 
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:
9 
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 
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.
22 
23 
24 #ifndef LUABIND_CLASS_HPP_INCLUDED
25 #define LUABIND_CLASS_HPP_INCLUDED
26 
27 /*
28 	ISSUES:
29 	------------------------------------------------------
30 
31 	* solved for member functions, not application operator *
32 	if we have a base class that defines a function a derived class must be able to
33 	override that function (not just overload). Right now we just add the other overload
34 	to the overloads list and will probably get an ambiguity. If we want to support this
35 	each method_rep must include a vector of type_info pointers for each parameter.
36 	Operators do not have this problem, since operators always have to have
37 	it's own type as one of the arguments, no ambiguity can occur. Application
38 	operator, on the other hand, would have this problem.
39 	Properties cannot be overloaded, so they should always be overridden.
40 	If this is to work for application operator, we really need to specify if an application
41 	operator is const or not.
42 
43 	If one class registers two functions with the same name and the same
44 	signature, there's currently no error. The last registered function will
45 	be the one that's used.
46 	How do we know which class registered the function? If the function was
47 	defined by the base class, it is a legal operation, to override it.
48 	we cannot look at the pointer offset, since it always will be zero for one of the bases.
49 
50 
51 
52 	TODO:
53 	------------------------------------------------------
54 
55  	finish smart pointer support
56 		* the adopt policy should not be able to adopt pointers to held_types. This
57 		must be prohibited.
58 		* name_of_type must recognize holder_types and not return "custom"
59 
60 	document custom policies, custom converters
61 
62 	store the instance object for policies.
63 
64 	support the __concat metamethod. This is a bit tricky, since it cannot be
65 	treated as a normal operator. It is a binary operator but we want to use the
66 	__tostring implementation for both arguments.
67 
68 */
69 
70 #include <luabind/prefix.hpp>
71 #include <luabind/config.hpp>
72 
73 #include <string>
74 #include <map>
75 #include <vector>
76 #include <cassert>
77 
78 #include <boost/bind.hpp>
79 #include <boost/preprocessor/repetition/enum_params.hpp>
80 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
81 #include <boost/preprocessor/repetition/repeat.hpp>
82 #include <boost/type_traits/is_same.hpp>
83 #include <boost/type_traits/is_member_object_pointer.hpp>
84 #include <boost/mpl/apply.hpp>
85 #include <boost/mpl/lambda.hpp>
86 #include <boost/mpl/logical.hpp>
87 #include <boost/mpl/find_if.hpp>
88 #include <boost/mpl/eval_if.hpp>
89 #include <boost/mpl/logical.hpp>
90 
91 #include <luabind/config.hpp>
92 #include <luabind/scope.hpp>
93 #include <luabind/back_reference.hpp>
94 #include <luabind/function.hpp>
95 #include <luabind/dependency_policy.hpp>
96 #include <luabind/detail/constructor.hpp>
97 #include <luabind/detail/call.hpp>
98 #include <luabind/detail/deduce_signature.hpp>
99 #include <luabind/detail/compute_score.hpp>
100 #include <luabind/detail/primitives.hpp>
101 #include <luabind/detail/property.hpp>
102 #include <luabind/detail/typetraits.hpp>
103 #include <luabind/detail/class_rep.hpp>
104 #include <luabind/detail/call.hpp>
105 #include <luabind/detail/object_rep.hpp>
106 #include <luabind/detail/calc_arity.hpp>
107 #include <luabind/detail/call_member.hpp>
108 #include <luabind/detail/enum_maker.hpp>
109 #include <luabind/detail/operator_id.hpp>
110 #include <luabind/detail/pointee_typeid.hpp>
111 #include <luabind/detail/link_compatibility.hpp>
112 #include <luabind/detail/inheritance.hpp>
113 #include <luabind/typeid.hpp>
114 
115 // to remove the 'this' used in initialization list-warning
116 #ifdef _MSC_VER
117 #pragma warning(push)
118 #pragma warning(disable: 4355)
119 #endif
120 
121 namespace boost
122 {
123 
124   template <class T> class shared_ptr;
125 
126 } // namespace boost
127 
128 namespace luabind
129 {
130 	namespace detail
131 	{
132 		struct unspecified {};
133 
134 		template<class Derived> struct operator_;
135 
136 		struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
137 	}
138 
139 	template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
140 	struct class_;
141 
142 	// TODO: this function will only be invoked if the user hasn't defined a correct overload
143 	// maybe we should have a static assert in here?
144 	inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
get_const_holder(...)145 	get_const_holder(...)
146 	{
147 		return 0;
148 	}
149 
150 	template <class T>
get_const_holder(boost::shared_ptr<T> *)151 	boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
152 	{
153 		return 0;
154 	}
155 
156     template <
157         BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
158             LUABIND_MAX_BASES, class A, detail::null_type)
159     >
160     struct bases
161     {};
162 
163     typedef bases<detail::null_type> no_bases;
164 
165 	namespace detail
166 	{
167         template <class T>
168         struct is_bases
169           : mpl::false_
170         {};
171 
172         template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
173         struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
174           : mpl::true_
175         {};
176 
177         template <class T, class P>
178         struct is_unspecified
179           : mpl::apply1<P, T>
180         {};
181 
182         template <class P>
183         struct is_unspecified<unspecified, P>
184           : mpl::true_
185         {};
186 
187         template <class P>
188         struct is_unspecified_mfn
189         {
190             template <class T>
191             struct apply
192               : is_unspecified<T, P>
193             {};
194         };
195 
196 		template<class Predicate>
197 		struct get_predicate
198 		{
199             typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
200 		};
201 
202         template <class Result, class Default>
203         struct result_or_default
204         {
205             typedef Result type;
206         };
207 
208         template <class Default>
209         struct result_or_default<unspecified, Default>
210         {
211             typedef Default type;
212         };
213 
214 		template<class Parameters, class Predicate, class DefaultValue>
215 		struct extract_parameter
216 		{
217 			typedef typename get_predicate<Predicate>::type pred;
218 			typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
219             typedef typename result_or_default<
220                 typename iterator::type, DefaultValue
221             >::type type;
222 		};
223 
224 		// prints the types of the values on the stack, in the
225 		// range [start_index, lua_gettop()]
226 
227 		LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
228 
229 		struct LUABIND_API create_class
230 		{
231 			static int stage1(lua_State* L);
232 			static int stage2(lua_State* L);
233 		};
234 
235 	} // detail
236 
237 	namespace detail {
238 
239 		template<class T>
240 		struct static_scope
241 		{
static_scopeluabind::detail::static_scope242 			static_scope(T& self_) : self(self_)
243 			{
244 			}
245 
operator []luabind::detail::static_scope246 			T& operator[](scope s) const
247 			{
248 				self.add_inner_scope(s);
249 				return self;
250 			}
251 
252 		private:
253 			template<class U> void operator,(U const&) const;
254 			void operator=(static_scope const&);
255 
256 			T& self;
257 		};
258 
259 		struct class_registration;
260 
261 		struct LUABIND_API class_base : scope
262 		{
263 		public:
264 			class_base(char const* name);
265 
266 			struct base_desc
267 			{
268 				type_id type;
269 				int ptr_offset;
270 			};
271 
272 			void init(
273                 type_id const& type, class_id id
274               , type_id const& wrapped_type, class_id wrapper_id);
275 
276             void add_base(type_id const& base, cast_function cast);
277 
278 			void add_member(registration* member);
279 			void add_default_member(registration* member);
280 
281 			const char* name() const;
282 
283 			void add_static_constant(const char* name, int val);
284 			void add_inner_scope(scope& s);
285 
286             void add_cast(class_id src, class_id target, cast_function cast);
287 
288 		private:
289 			class_registration* m_registration;
290 		};
291 
292 // MSVC complains about member being sensitive to alignment (C4121)
293 // when F is a pointer to member of a class with virtual bases.
294 # ifdef BOOST_MSVC
295 #  pragma pack(push)
296 #  pragma pack(16)
297 # endif
298 
299 		template <class Class, class F, class Policies>
300 		struct memfun_registration : registration
301 		{
memfun_registrationluabind::detail::memfun_registration302 			memfun_registration(char const* name, F f, Policies const& policies)
303 			  : name(name)
304 			  , f(f)
305 			  , policies(policies)
306 			{}
307 
register_luabind::detail::memfun_registration308 			void register_(lua_State* L) const
309 			{
310 				object fn = make_function(
311 					L, f, deduce_signature(f, (Class*)0), policies);
312 
313 				add_overload(
314 					object(from_stack(L, -1))
315 				  , name
316 				  , fn
317 				);
318 			}
319 
320 			char const* name;
321 			F f;
322 			Policies policies;
323 		};
324 
325 # ifdef BOOST_MSVC
326 #  pragma pack(pop)
327 # endif
328 
329         template <class P, class T>
330         struct default_pointer
331         {
332             typedef P type;
333         };
334 
335         template <class T>
336         struct default_pointer<null_type, T>
337         {
338             typedef std::auto_ptr<T> type;
339         };
340 
341         template <class Class, class Pointer, class Signature, class Policies>
342         struct constructor_registration : registration
343         {
constructor_registrationluabind::detail::constructor_registration344             constructor_registration(Policies const& policies)
345               : policies(policies)
346             {}
347 
register_luabind::detail::constructor_registration348             void register_(lua_State* L) const
349             {
350                 typedef typename default_pointer<Pointer, Class>::type pointer;
351 
352                 object fn = make_function(
353                     L
354                   , construct<Class, pointer, Signature>(), Signature()
355                   , policies
356                 );
357 
358                 add_overload(
359                     object(from_stack(L, -1))
360                   , "__init"
361                   , fn
362                 );
363             }
364 
365             Policies policies;
366         };
367 
368         template <class T>
369         struct reference_result
370           : mpl::if_<
371                 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
372               , T
373               , typename boost::add_reference<T>::type
374             >
375         {};
376 
377         template <class T, class Policies>
378         struct inject_dependency_policy
379           : mpl::if_<
380                 is_primitive<T>
381               , Policies
382               , policy_cons<dependency_policy<0, 1>, Policies>
383             >
384         {};
385 
386         template <
387             class Class
388           , class Get, class GetPolicies
389           , class Set = null_type, class SetPolicies = null_type
390         >
391         struct property_registration : registration
392         {
property_registrationluabind::detail::property_registration393             property_registration(
394                 char const* name
395               , Get const& get
396               , GetPolicies const& get_policies
397               , Set const& set = Set()
398               , SetPolicies const& set_policies = SetPolicies()
399             )
400               : name(name)
401               , get(get)
402               , get_policies(get_policies)
403               , set(set)
404               , set_policies(set_policies)
405             {}
406 
register_luabind::detail::property_registration407             void register_(lua_State* L) const
408             {
409                 object context(from_stack(L, -1));
410                 register_aux(
411                     L
412                   , context
413                   , make_get(L, get, boost::is_member_object_pointer<Get>())
414                   , set
415                 );
416             }
417 
418             template <class F>
make_getluabind::detail::property_registration419             object make_get(lua_State* L, F const& f, mpl::false_) const
420             {
421                 return make_function(
422                     L, f, deduce_signature(f, (Class*)0), get_policies);
423             }
424 
425             template <class T, class D>
make_getluabind::detail::property_registration426             object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
427             {
428                 typedef typename reference_result<D>::type result_type;
429                 typedef typename inject_dependency_policy<
430                     D, GetPolicies>::type policies;
431 
432                 return make_function(
433                     L
434                   , access_member_ptr<T, D, result_type>(mem_ptr)
435                   , mpl::vector2<result_type, Class const&>()
436                   , policies()
437                 );
438             }
439 
440             template <class F>
make_setluabind::detail::property_registration441             object make_set(lua_State* L, F const& f, mpl::false_) const
442             {
443                 return make_function(
444                     L, f, deduce_signature(f, (Class*)0), set_policies);
445             }
446 
447             template <class T, class D>
make_setluabind::detail::property_registration448             object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
449             {
450                 return make_function(
451                     L
452                   , access_member_ptr<T, D>(mem_ptr)
453                   , mpl::vector3<void, Class&, D const&>()
454                   , set_policies
455                 );
456             }
457 
458             template <class S>
register_auxluabind::detail::property_registration459             void register_aux(
460                 lua_State* L, object const& context
461               , object const& get_, S const&) const
462             {
463                 context[name] = property(
464                     get_
465                   , make_set(L, set, boost::is_member_object_pointer<Set>())
466                 );
467             }
468 
register_auxluabind::detail::property_registration469             void register_aux(
470                 lua_State*, object const& context
471               , object const& get_, null_type) const
472             {
473                 context[name] = property(get_);
474             }
475 
476             char const* name;
477             Get get;
478             GetPolicies get_policies;
479             Set set;
480             SetPolicies set_policies;
481         };
482 
483 	} // namespace detail
484 
485 	// registers a class in the lua environment
486 	template<class T, class X1, class X2, class X3>
487 	struct class_: detail::class_base
488 	{
489 		typedef class_<T, X1, X2, X3> self_t;
490 
491 	private:
492 
493 		template<class A, class B, class C, class D>
494 		class_(const class_<A,B,C,D>&);
495 
496 	public:
497 
498         typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
499 
500 		// WrappedType MUST inherit from T
501 		typedef typename detail::extract_parameter<
502 		    parameters_type
503 		  , boost::is_base_and_derived<T, boost::mpl::_>
504 		  , detail::null_type
505 		>::type WrappedType;
506 
507 		typedef typename detail::extract_parameter<
508 		    parameters_type
509 		  , boost::mpl::not_<
510 		        boost::mpl::or_<
511                     detail::is_bases<boost::mpl::_>
512                   , boost::is_base_and_derived<boost::mpl::_, T>
513                   , boost::is_base_and_derived<T, boost::mpl::_>
514 				>
515 			>
516 		  , detail::null_type
517 		>::type HeldType;
518 
519         template <class Src, class Target>
add_downcastluabind::class_520         void add_downcast(Src*, Target*, boost::mpl::true_)
521         {
522             add_cast(
523                 detail::registered_class<Src>::id
524               , detail::registered_class<Target>::id
525               , detail::dynamic_cast_<Src, Target>::execute
526             );
527         }
528 
529         template <class Src, class Target>
add_downcastluabind::class_530         void add_downcast(Src*, Target*, boost::mpl::false_)
531         {}
532 
533 		// this function generates conversion information
534 		// in the given class_rep structure. It will be able
535 		// to implicitly cast to the given template type
536 		template<class To>
gen_base_infoluabind::class_537 		void gen_base_info(detail::type_<To>)
538 		{
539             add_base(typeid(To), detail::static_cast_<T, To>::execute);
540             add_cast(
541                 detail::registered_class<T>::id
542               , detail::registered_class<To>::id
543               , detail::static_cast_<T, To>::execute
544             );
545 
546             add_downcast((To*)0, (T*)0, boost::is_polymorphic<To>());
547 		}
548 
gen_base_infoluabind::class_549 		void gen_base_info(detail::type_<detail::null_type>)
550 		{}
551 
552 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<BaseClass##n>());
553 
554 		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class BaseClass)>
generate_baseclass_listluabind::class_555 		void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, BaseClass)> >)
556 		{
557 			BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
558 		}
559 
560 #undef LUABIND_GEN_BASE_INFO
561 
class_luabind::class_562 		class_(const char* name): class_base(name), scope(*this)
563 		{
564 #ifndef NDEBUG
565 			detail::check_link_compatibility();
566 #endif
567 		   	init();
568 		}
569 
570 		template<class F>
defluabind::class_571 		class_& def(const char* name, F f)
572 		{
573 			return this->virtual_def(
574 				name, f, detail::null_type()
575 			  , detail::null_type(), boost::mpl::true_());
576 		}
577 
578 		// virtual functions
579 		template<class F, class DefaultOrPolicies>
defluabind::class_580 		class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
581 		{
582 			return this->virtual_def(
583 				name, fn, default_or_policies, detail::null_type()
584 			  , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
585 		}
586 
587 		template<class F, class Default, class Policies>
defluabind::class_588 		class_& def(char const* name, F fn
589 			, Default default_, Policies const& policies)
590 		{
591 			return this->virtual_def(
592 				name, fn, default_
593 			  , policies, boost::mpl::false_());
594 		}
595 
596 		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
defluabind::class_597 		class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
598 		{
599             return this->def_constructor(&sig, detail::null_type());
600 		}
601 
602 		template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
defluabind::class_603 		class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
604 		{
605             return this->def_constructor(&sig, policies);
606 		}
607 
608         template <class Getter>
propertyluabind::class_609         class_& property(const char* name, Getter g)
610         {
611             this->add_member(
612                 new detail::property_registration<T, Getter, detail::null_type>(
613                     name, g, detail::null_type()));
614             return *this;
615         }
616 
617         template <class Getter, class MaybeSetter>
propertyluabind::class_618         class_& property(const char* name, Getter g, MaybeSetter s)
619         {
620             return property_impl(
621                 name, g, s
622               , boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
623             );
624         }
625 
626         template<class Getter, class Setter, class GetPolicies>
propertyluabind::class_627         class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
628         {
629             typedef detail::property_registration<
630                 T, Getter, GetPolicies, Setter, detail::null_type
631             > registration_type;
632 
633             this->add_member(
634                 new registration_type(name, g, get_policies, s));
635             return *this;
636         }
637 
638         template<class Getter, class Setter, class GetPolicies, class SetPolicies>
propertyluabind::class_639         class_& property(
640             const char* name
641           , Getter g, Setter s
642           , GetPolicies const& get_policies
643           , SetPolicies const& set_policies)
644         {
645             typedef detail::property_registration<
646                 T, Getter, GetPolicies, Setter, SetPolicies
647             > registration_type;
648 
649             this->add_member(
650                 new registration_type(name, g, get_policies, s, set_policies));
651             return *this;
652         }
653 
654         template <class C, class D>
def_readonlyluabind::class_655         class_& def_readonly(const char* name, D C::*mem_ptr)
656         {
657             typedef detail::property_registration<T, D C::*, detail::null_type>
658                 registration_type;
659 
660             this->add_member(
661                 new registration_type(name, mem_ptr, detail::null_type()));
662             return *this;
663         }
664 
665         template <class C, class D, class Policies>
def_readonlyluabind::class_666         class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies)
667         {
668             typedef detail::property_registration<T, D C::*, Policies>
669                 registration_type;
670 
671             this->add_member(
672                 new registration_type(name, mem_ptr, policies));
673             return *this;
674         }
675 
676         template <class C, class D>
def_readwriteluabind::class_677         class_& def_readwrite(const char* name, D C::*mem_ptr)
678         {
679             typedef detail::property_registration<
680                 T, D C::*, detail::null_type, D C::*
681             > registration_type;
682 
683             this->add_member(
684                 new registration_type(
685                     name, mem_ptr, detail::null_type(), mem_ptr));
686             return *this;
687         }
688 
689         template <class C, class D, class GetPolicies>
def_readwriteluabind::class_690         class_& def_readwrite(
691             const char* name, D C::*mem_ptr, GetPolicies const& get_policies)
692         {
693             typedef detail::property_registration<
694                 T, D C::*, GetPolicies, D C::*
695             > registration_type;
696 
697             this->add_member(
698                 new registration_type(
699                     name, mem_ptr, get_policies, mem_ptr));
700             return *this;
701         }
702 
703         template <class C, class D, class GetPolicies, class SetPolicies>
def_readwriteluabind::class_704         class_& def_readwrite(
705             const char* name
706           , D C::*mem_ptr
707           , GetPolicies const& get_policies
708           , SetPolicies const& set_policies
709         )
710         {
711             typedef detail::property_registration<
712                 T, D C::*, GetPolicies, D C::*, SetPolicies
713             > registration_type;
714 
715             this->add_member(
716                 new registration_type(
717                     name, mem_ptr, get_policies, mem_ptr, set_policies));
718             return *this;
719         }
720 
721 		template<class Derived, class Policies>
defluabind::class_722 		class_& def(detail::operator_<Derived>, Policies const& policies)
723 		{
724 			return this->def(
725 				Derived::name()
726 			  , &Derived::template apply<T, Policies>::execute
727 			  , policies
728 			);
729 		}
730 
731 		template<class Derived>
defluabind::class_732 		class_& def(detail::operator_<Derived>)
733 		{
734 			return this->def(
735 				Derived::name()
736 			  , &Derived::template apply<T, detail::null_type>::execute
737 			);
738 		}
739 
enum_luabind::class_740 		detail::enum_maker<self_t> enum_(const char*)
741 		{
742 			return detail::enum_maker<self_t>(*this);
743 		}
744 
745 		detail::static_scope<self_t> scope;
746 
747 	private:
748 		void operator=(class_ const&);
749 
add_wrapper_castluabind::class_750         void add_wrapper_cast(detail::null_type*)
751         {}
752 
753         template <class U>
add_wrapper_castluabind::class_754         void add_wrapper_cast(U*)
755         {
756             add_cast(
757                 detail::registered_class<U>::id
758               , detail::registered_class<T>::id
759               , detail::static_cast_<U,T>::execute
760             );
761 
762             add_downcast((T*)0, (U*)0, boost::is_polymorphic<T>());
763         }
764 
initluabind::class_765 		void init()
766 		{
767 			typedef typename detail::extract_parameter<
768 					parameters_type
769 				,	boost::mpl::or_<
770 							detail::is_bases<boost::mpl::_>
771 						,	boost::is_base_and_derived<boost::mpl::_, T>
772 					>
773 				,	no_bases
774 			>::type bases_t;
775 
776 			typedef typename
777 				boost::mpl::if_<detail::is_bases<bases_t>
778 					,	bases_t
779 					,	bases<bases_t>
780 				>::type Base;
781 
782             class_base::init(
783                 typeid(T)
784               , detail::registered_class<T>::id
785               , typeid(WrappedType)
786               , detail::registered_class<WrappedType>::id
787             );
788 
789             add_wrapper_cast((WrappedType*)0);
790 
791 			generate_baseclass_list(detail::type_<Base>());
792 		}
793 
794 		template<class Getter, class GetPolicies>
property_implluabind::class_795 		class_& property_impl(const char* name,
796 									 Getter g,
797 									 GetPolicies policies,
798 									 boost::mpl::bool_<true>)
799 		{
800             this->add_member(
801                 new detail::property_registration<T, Getter, GetPolicies>(
802                     name, g, policies));
803 			return *this;
804 		}
805 
806 		template<class Getter, class Setter>
property_implluabind::class_807 		class_& property_impl(const char* name,
808 									 Getter g,
809 									 Setter s,
810 									 boost::mpl::bool_<false>)
811 		{
812             typedef detail::property_registration<
813                 T, Getter, detail::null_type, Setter, detail::null_type
814             > registration_type;
815 
816             this->add_member(
817                 new registration_type(name, g, detail::null_type(), s));
818 			return *this;
819 		}
820 
821 		// these handle default implementation of virtual functions
822 		template<class F, class Policies>
virtual_defluabind::class_823 		class_& virtual_def(char const* name, F const& fn
824 			, Policies const&, detail::null_type, boost::mpl::true_)
825 		{
826 			this->add_member(
827 				new detail::memfun_registration<T, F, Policies>(
828 					name, fn, Policies()));
829 			return *this;
830 		}
831 
832 		template<class F, class Default, class Policies>
virtual_defluabind::class_833 		class_& virtual_def(char const* name, F const& fn
834 			, Default const& default_, Policies const&, boost::mpl::false_)
835 		{
836 			this->add_member(
837 				new detail::memfun_registration<T, F, Policies>(
838 					name, fn, Policies()));
839 
840 			this->add_default_member(
841 				new detail::memfun_registration<T, Default, Policies>(
842 					name, default_, Policies()));
843 
844 			return *this;
845 		}
846 
847         template<class Signature, class Policies>
def_constructorluabind::class_848 		class_& def_constructor(Signature*, Policies const&)
849         {
850             typedef typename Signature::signature signature;
851 
852             typedef typename boost::mpl::if_<
853                 boost::is_same<WrappedType, detail::null_type>
854               , T
855               , WrappedType
856             >::type construct_type;
857 
858             this->add_member(
859                 new detail::constructor_registration<
860                     construct_type, HeldType, signature, Policies>(
861                         Policies()));
862 
863             this->add_default_member(
864                 new detail::constructor_registration<
865                     construct_type, HeldType, signature, Policies>(
866                         Policies()));
867 
868             return *this;
869         }
870 	};
871 
872 }
873 
874 #ifdef _MSC_VER
875 #pragma warning(pop)
876 #endif
877 
878 #endif // LUABIND_CLASS_HPP_INCLUDED
879 
880