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 
72 #include <luabind/back_reference.hpp>
73 #include <luabind/config.hpp>
74 #include <luabind/dependency_policy.hpp>
75 #include <luabind/detail/call.hpp>
76 #include <luabind/detail/call_member.hpp>
77 #include <luabind/detail/class_rep.hpp>
78 #include <luabind/detail/constructor.hpp>
79 #include <luabind/detail/deduce_signature.hpp>
80 #include <luabind/detail/enum_maker.hpp>
81 #include <luabind/detail/inheritance.hpp>
82 #include <luabind/detail/link_compatibility.hpp>
83 #include <luabind/detail/object_rep.hpp>
84 #include <luabind/detail/operator_id.hpp>
85 #include <luabind/detail/primitives.hpp>
86 #include <luabind/detail/property.hpp>
87 #include <luabind/detail/signature_match.hpp>
88 #include <luabind/detail/typetraits.hpp>
89 #include <luabind/function.hpp>
90 #include <luabind/no_dependency.hpp>
91 #include <luabind/scope.hpp>
92 #include <luabind/typeid.hpp>
93 
94 #include <boost/bind.hpp>
95 #include <boost/mpl/apply.hpp>
96 #include <boost/mpl/eval_if.hpp>
97 #include <boost/mpl/find_if.hpp>
98 #include <boost/mpl/lambda.hpp>
99 #include <boost/mpl/logical.hpp>
100 #include <boost/preprocessor/repetition/enum_params.hpp>
101 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
102 #include <boost/preprocessor/repetition/repeat.hpp>
103 #include <boost/type_traits/is_member_object_pointer.hpp>
104 #include <boost/type_traits/is_same.hpp>
105 
106 #include <cassert>
107 #include <map>
108 #include <string>
109 #include <vector>
110 
111 // to remove the 'this' used in initialization list-warning
112 #ifdef _MSC_VER
113 #pragma warning(push)
114 #pragma warning(disable: 4355)
115 #endif
116 
117 namespace boost
118 {
119 
120   template <class T> class shared_ptr;
121 
122 } // namespace boost
123 
124 namespace luabind
125 {
126     namespace detail
127     {
128         struct unspecified {};
129 
130         template<class Derived> struct operator_;
131     }
132 
133     template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
134     struct class_;
135 
136     template <
137         BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
138             LUABIND_MAX_BASES, class A, detail::null_type)
139     >
140     struct bases
141     {};
142 
143     typedef bases<detail::null_type> no_bases;
144 
145     namespace detail
146     {
147         template <class T>
148         struct is_bases
149           : mpl::false_
150         {};
151 
152         template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
153         struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
154           : mpl::true_
155         {};
156 
157         template <class T, class P>
158         struct is_unspecified
159           : mpl::apply1<P, T>
160         {};
161 
162         template <class P>
163         struct is_unspecified<unspecified, P>
164           : mpl::true_
165         {};
166 
167         template <class P>
168         struct is_unspecified_mfn
169         {
170             template <class T>
171             struct apply
172               : is_unspecified<T, P>
173             {};
174         };
175 
176         template<class Predicate>
177         struct get_predicate
178         {
179             typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
180         };
181 
182         template <class Result, class Default>
183         struct result_or_default
184         {
185             typedef Result type;
186         };
187 
188         template <class Default>
189         struct result_or_default<unspecified, Default>
190         {
191             typedef Default type;
192         };
193 
194         template<class Parameters, class Predicate, class DefaultValue>
195         struct extract_parameter
196         {
197             typedef typename get_predicate<Predicate>::type pred;
198             typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
199             typedef typename result_or_default<
200                 typename iterator::type, DefaultValue
201             >::type type;
202         };
203 
204         struct LUABIND_API create_class
205         {
206             static int stage1(lua_State* L);
207             static int stage2(lua_State* L);
208         };
209 
210     } // detail
211 
212     namespace detail {
213 
214         template<class T>
215         struct static_scope
216         {
static_scopeluabind::detail::static_scope217             static_scope(T& self_) : self(self_)
218             {
219             }
220 
operator []luabind::detail::static_scope221             T& operator[](scope s) const
222             {
223                 self.add_inner_scope(s);
224                 return self;
225             }
226 
227         private:
228             template<class U> void operator,(U const&) const;
229             void operator=(static_scope const&);
230 
231             T& self;
232         };
233 
234         struct class_registration;
235 
236         struct LUABIND_API class_base : scope
237         {
238         public:
239             class_base(char const* name);
240 
241             void init(
242                 type_id const& type, class_id id
243               , type_id const& wrapped_type, class_id wrapper_id);
244 
245             void add_base(type_id const& base);
246 
247             void add_member(registration* member);
248             void add_default_member(registration* member);
249 
250             const char* name() const;
251 
252             void add_static_constant(const char* name, int val);
253             void add_inner_scope(scope& s);
254 
255             void add_cast(class_id src, class_id target, cast_function cast);
256 
257         private:
258             class_registration* m_registration;
259         };
260 
261 // MSVC complains about member being sensitive to alignment (C4121)
262 // when F is a pointer to member of a class with virtual bases.
263 # ifdef BOOST_MSVC
264 #  pragma pack(push)
265 #  pragma pack(16)
266 # endif
267 
268         template <class Class, class F, class Policies>
269         struct memfun_registration : registration
270         {
memfun_registrationluabind::detail::memfun_registration271             memfun_registration(char const* name_, F f_, Policies const& policies_)
272               : name(name_)
273               , f(f_)
274               , policies(policies_)
275             {}
276 
register_luabind::detail::memfun_registration277             void register_(lua_State* L) const
278             {
279                 object fn = make_function(
280                     L, f, deduce_signature(f, static_cast<Class*>(0)), policies);
281 
282                 add_overload(
283                     object(from_stack(L, -1))
284                   , name
285                   , fn
286                 );
287             }
288 
289             char const* name;
290             F f;
291             Policies policies;
292         };
293 
294 # ifdef BOOST_MSVC
295 #  pragma pack(pop)
296 # endif
297 
298         template <class P, class T>
299         struct default_pointer
300         {
301             typedef P type;
302         };
303 
304         template <class T>
305         struct default_pointer<null_type, T>
306         {
307 #ifdef LUABIND_USE_CXX11
308             typedef std::unique_ptr<T> type;
309 #else
310             typedef std::auto_ptr<T> type;
311 #endif
312         };
313 
314         template <class Class, class Pointer, class Signature, class Policies>
315         struct constructor_registration : registration
316         {
constructor_registrationluabind::detail::constructor_registration317             constructor_registration(Policies const& policies_)
318               : policies(policies_)
319             {}
320 
register_luabind::detail::constructor_registration321             void register_(lua_State* L) const
322             {
323                 typedef typename default_pointer<Pointer, Class>::type pointer;
324 
325                 object fn = make_function(
326                     L
327                   , construct<Class, pointer, Signature>(), Signature()
328                   , policies
329                 );
330 
331                 add_overload(
332                     object(from_stack(L, -1))
333                   , "__init"
334                   , fn
335                 );
336             }
337 
338             Policies policies;
339         };
340 
341         template <class T>
342         struct reference_result
343           : mpl::if_<
344                 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
345               , T
346               , typename boost::add_reference<T>::type
347             >
348         {};
349 
350         template <class T>
351         struct reference_argument
352           : mpl::if_<
353                 mpl::or_<boost::is_pointer<T>, is_primitive<T> >
354               , T
355               , typename boost::add_reference<
356                     typename boost::add_const<T>::type
357                 >::type
358             >
359         {};
360 
361         template <class T, class Policies>
362         struct inject_dependency_policy
363           : mpl::if_<
364                 mpl::or_<
365                     is_primitive<T>
366                   , has_policy<Policies, detail::no_dependency_policy>
367                 >
368               , Policies
369               , policy_cons<dependency_policy<0, 1>, Policies>
370             >
371         {};
372 
373         template <
374             class Class
375           , class Get, class GetPolicies
376           , class Set = null_type, class SetPolicies = null_type
377         >
378         struct property_registration : registration
379         {
property_registrationluabind::detail::property_registration380             property_registration(
381                 char const* name_
382               , Get const& get_
383               , GetPolicies const& get_policies_
384               , Set const& set_ = Set()
385               , SetPolicies const& set_policies_ = SetPolicies()
386             )
387               : set(set_)
388               , set_policies(set_policies_)
389               , get(get_)
390               , get_policies(get_policies_)
391               , name(name_)
392             {}
393 
register_luabind::detail::property_registration394             void register_(lua_State* L) const
395             {
396                 object context(from_stack(L, -1));
397                 register_aux(
398                     L
399                   , context
400                   , make_get(L, get, boost::is_member_object_pointer<Get>())
401                   , set
402                 );
403             }
404 
405             template <class F>
make_getluabind::detail::property_registration406             object make_get(lua_State* L, F const& f, mpl::false_) const
407             {
408                 return make_function(
409                     L, f, deduce_signature(f, static_cast<Class*>(0)), get_policies);
410             }
411 
412             template <class T, class D>
make_getluabind::detail::property_registration413             object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
414             {
415                 typedef typename reference_result<D>::type result_type;
416                 typedef typename inject_dependency_policy<
417                     D, GetPolicies>::type policies;
418 
419                 return make_function(
420                     L
421                   , access_member_ptr<T, D, result_type>(mem_ptr)
422                   , mpl::vector2<result_type, Class const&>()
423                   , policies()
424                 );
425             }
426 
427             template <class F>
make_setluabind::detail::property_registration428             object make_set(lua_State* L, F const& f, mpl::false_) const
429             {
430                 return make_function(
431                     L, f, deduce_signature(f, static_cast<Class*>(0)), set_policies);
432             }
433 
434             template <class T, class D>
make_setluabind::detail::property_registration435             object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
436             {
437                 typedef typename reference_argument<D>::type argument_type;
438 
439                 return make_function(
440                     L
441                   , access_member_ptr<T, D>(mem_ptr)
442                   , mpl::vector3<void, Class&, argument_type>()
443                   , set_policies
444                 );
445             }
446 
447             template <class S>
register_auxluabind::detail::property_registration448             void register_aux(
449                 lua_State* L, object const& context
450               , object const& get_, S const&) const
451             {
452                 context[name] = property(
453                     get_
454                   , make_set(L, set, boost::is_member_object_pointer<Set>())
455                 );
456             }
457 
register_auxluabind::detail::property_registration458             void register_aux(
459                 lua_State*, object const& context
460               , object const& get_, null_type) const
461             {
462                 context[name] = property(get_);
463             }
464 
465             Set set;
466             SetPolicies set_policies;
467             Get get;
468             GetPolicies get_policies;
469             char const* name;
470         };
471 
472     } // namespace detail
473 
474     // registers a class in the lua environment
475     template<class T, class X1, class X2, class X3>
476     struct class_: detail::class_base
477     {
478         typedef class_<T, X1, X2, X3> self_t;
479 
480     private:
481 
482         template<class A, class B, class C, class D>
483         class_(const class_<A,B,C,D>&);
484 
485     public:
486 
487         typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
488 
489         // WrappedType MUST inherit from T
490         typedef typename detail::extract_parameter<
491             parameters_type
492           , boost::is_base_and_derived<T, boost::mpl::_>
493           , detail::null_type
494         >::type WrappedType;
495 
496         typedef typename detail::extract_parameter<
497             parameters_type
498           , boost::mpl::not_<
499                 boost::mpl::or_<
500                     detail::is_bases<boost::mpl::_>
501                   , boost::is_base_and_derived<boost::mpl::_, T>
502                   , boost::is_base_and_derived<T, boost::mpl::_>
503                 >
504             >
505           , detail::null_type
506         >::type HeldType;
507 
508         template <class Src, class Target>
add_downcastluabind::class_509         void add_downcast(Src*, Target*, boost::mpl::true_)
510         {
511             add_cast(
512                 detail::registered_class<Src>::id
513               , detail::registered_class<Target>::id
514               , detail::dynamic_cast_<Src, Target>::execute
515             );
516         }
517 
518         template <class Src, class Target>
add_downcastluabind::class_519         void add_downcast(Src*, Target*, boost::mpl::false_)
520         {}
521 
522         // this function generates conversion information
523         // in the given class_rep structure. It will be able
524         // to implicitly cast to the given template type
525         template<class To>
gen_base_infoluabind::class_526         void gen_base_info(detail::type_<To>)
527         {
528             add_base(typeid(To));
529             add_cast(
530                 detail::registered_class<T>::id
531               , detail::registered_class<To>::id
532               , detail::static_cast_<T, To>::execute
533             );
534 
535             add_downcast(static_cast<To*>(0), static_cast<T*>(0), boost::is_polymorphic<To>());
536         }
537 
gen_base_infoluabind::class_538         void gen_base_info(detail::type_<detail::null_type>)
539         {}
540 
541 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<BaseClass##n>());
542 
543         template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class BaseClass)>
generate_baseclass_listluabind::class_544         void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, BaseClass)> >)
545         {
546             BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
547         }
548 
549 #undef LUABIND_GEN_BASE_INFO
550 
class_luabind::class_551         class_(const char* name_ = 0): class_base(name_), scope(*this)
552         {
553 #ifndef NDEBUG
554             detail::check_link_compatibility();
555 #endif
556             init();
557         }
558 
559         template<class F>
defluabind::class_560         class_& def(const char* name_, F f)
561         {
562             return this->virtual_def(
563                 name_, f, detail::null_type()
564               , detail::null_type(), boost::mpl::true_());
565         }
566 
567         // virtual functions
568         template<class F, class DefaultOrPolicies>
defluabind::class_569         class_& def(char const* name_, F fn, DefaultOrPolicies default_or_policies)
570         {
571             return this->virtual_def(
572                 name_, fn, default_or_policies, detail::null_type()
573               , typename detail::is_policy_cons<DefaultOrPolicies>::type());
574         }
575 
576         template<class F, class Default, class Policies>
defluabind::class_577         class_& def(char const* name_, F fn
578             , Default default_, Policies const& policies)
579         {
580             return this->virtual_def(
581                 name_, fn, default_
582               , policies, boost::mpl::false_());
583         }
584 
585         template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
defluabind::class_586         class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
587         {
588             return this->def_constructor(&sig, detail::null_type());
589         }
590 
591         template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
defluabind::class_592         class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
593         {
594             return this->def_constructor(&sig, policies);
595         }
596 
597         template <class Getter>
propertyluabind::class_598         class_& property(const char* name_, Getter g)
599         {
600             this->add_member(
601                 new detail::property_registration<T, Getter, detail::null_type>(
602                     name_, g, detail::null_type()));
603             return *this;
604         }
605 
606         template <class Getter, class MaybeSetter>
propertyluabind::class_607         class_& property(const char* name_, Getter g, MaybeSetter s)
608         {
609             return property_impl(
610                 name_, g, s
611               , boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
612             );
613         }
614 
615         template<class Getter, class Setter, class GetPolicies>
propertyluabind::class_616         class_& property(const char* name_, Getter g, Setter s, const GetPolicies& get_policies)
617         {
618             typedef detail::property_registration<
619                 T, Getter, GetPolicies, Setter, detail::null_type
620             > registration_type;
621 
622             this->add_member(
623                 new registration_type(name_, g, get_policies, s));
624             return *this;
625         }
626 
627         template<class Getter, class Setter, class GetPolicies, class SetPolicies>
propertyluabind::class_628         class_& property(
629             const char* name_
630           , Getter g, Setter s
631           , GetPolicies const& get_policies
632           , SetPolicies const& set_policies)
633         {
634             typedef detail::property_registration<
635                 T, Getter, GetPolicies, Setter, SetPolicies
636             > registration_type;
637 
638             this->add_member(
639                 new registration_type(name_, g, get_policies, s, set_policies));
640             return *this;
641         }
642 
643         template <class C, class D>
def_readonlyluabind::class_644         class_& def_readonly(const char* name_, D C::*mem_ptr)
645         {
646             typedef detail::property_registration<T, D C::*, detail::null_type>
647                 registration_type;
648 
649             this->add_member(
650                 new registration_type(name_, mem_ptr, detail::null_type()));
651             return *this;
652         }
653 
654         template <class C, class D, class Policies>
def_readonlyluabind::class_655         class_& def_readonly(const char* name_, D C::*mem_ptr, Policies const& policies)
656         {
657             typedef detail::property_registration<T, D C::*, Policies>
658                 registration_type;
659 
660             this->add_member(
661                 new registration_type(name_, mem_ptr, policies));
662             return *this;
663         }
664 
665         template <class C, class D>
def_readwriteluabind::class_666         class_& def_readwrite(const char* name_, D C::*mem_ptr)
667         {
668             typedef detail::property_registration<
669                 T, D C::*, detail::null_type, D C::*
670             > registration_type;
671 
672             this->add_member(
673                 new registration_type(
674                     name_, mem_ptr, detail::null_type(), mem_ptr));
675             return *this;
676         }
677 
678         template <class C, class D, class GetPolicies>
def_readwriteluabind::class_679         class_& def_readwrite(
680             const char* name_, D C::*mem_ptr, GetPolicies const& get_policies)
681         {
682             typedef detail::property_registration<
683                 T, D C::*, GetPolicies, D C::*
684             > registration_type;
685 
686             this->add_member(
687                 new registration_type(
688                     name_, mem_ptr, get_policies, mem_ptr));
689             return *this;
690         }
691 
692         template <class C, class D, class GetPolicies, class SetPolicies>
def_readwriteluabind::class_693         class_& def_readwrite(
694             const char* name_
695           , D C::*mem_ptr
696           , GetPolicies const& get_policies
697           , SetPolicies const& set_policies
698         )
699         {
700             typedef detail::property_registration<
701                 T, D C::*, GetPolicies, D C::*, SetPolicies
702             > registration_type;
703 
704             this->add_member(
705                 new registration_type(
706                     name_, mem_ptr, get_policies, mem_ptr, set_policies));
707             return *this;
708         }
709 
710         template<class Derived, class Policies>
defluabind::class_711         class_& def(detail::operator_<Derived>, Policies const& policies)
712         {
713             return this->def(
714                 Derived::name()
715               , &Derived::template apply<T, Policies>::execute
716               , policies
717             );
718         }
719 
720         template<class Derived>
defluabind::class_721         class_& def(detail::operator_<Derived>)
722         {
723             return this->def(
724                 Derived::name()
725               , &Derived::template apply<T, detail::null_type>::execute
726             );
727         }
728 
enum_luabind::class_729         detail::enum_maker<self_t> enum_(const char*)
730         {
731             return detail::enum_maker<self_t>(*this);
732         }
733 
734         detail::static_scope<self_t> scope;
735 
736     private:
737         void operator=(class_ const&);
738 
add_wrapper_castluabind::class_739         void add_wrapper_cast(detail::null_type*)
740         {}
741 
742         template <class U>
add_wrapper_castluabind::class_743         void add_wrapper_cast(U*)
744         {
745             add_cast(
746                 detail::registered_class<U>::id
747               , detail::registered_class<T>::id
748               , detail::static_cast_<U,T>::execute
749             );
750 
751             add_downcast(static_cast<T*>(0), static_cast<U*>(0), boost::is_polymorphic<T>());
752         }
753 
initluabind::class_754         void init()
755         {
756             typedef typename detail::extract_parameter<
757                     parameters_type
758                 ,   boost::mpl::or_<
759                             detail::is_bases<boost::mpl::_>
760                         ,   boost::is_base_and_derived<boost::mpl::_, T>
761                     >
762                 ,   no_bases
763             >::type bases_t;
764 
765             typedef typename
766                 boost::mpl::if_<detail::is_bases<bases_t>
767                     ,   bases_t
768                     ,   bases<bases_t>
769                 >::type Base;
770 
771             class_base::init(
772                 typeid(T)
773               , detail::registered_class<T>::id
774               , typeid(WrappedType)
775               , detail::registered_class<WrappedType>::id
776             );
777 
778             add_wrapper_cast(static_cast<WrappedType*>(0));
779 
780             generate_baseclass_list(detail::type_<Base>());
781         }
782 
783         template<class Getter, class GetPolicies>
property_implluabind::class_784         class_& property_impl(const char* name_,
785                                      Getter g,
786                                      GetPolicies policies,
787                                      boost::mpl::bool_<true>)
788         {
789             this->add_member(
790                 new detail::property_registration<T, Getter, GetPolicies>(
791                     name_, g, policies));
792             return *this;
793         }
794 
795         template<class Getter, class Setter>
property_implluabind::class_796         class_& property_impl(const char* name_,
797                                      Getter g,
798                                      Setter s,
799                                      boost::mpl::bool_<false>)
800         {
801             typedef detail::property_registration<
802                 T, Getter, detail::null_type, Setter, detail::null_type
803             > registration_type;
804 
805             this->add_member(
806                 new registration_type(name_, g, detail::null_type(), s));
807             return *this;
808         }
809 
810         // these handle default implementation of virtual functions
811         template<class F, class Policies>
virtual_defluabind::class_812         class_& virtual_def(char const* name_, F const& fn
813             , Policies const&, detail::null_type, boost::mpl::true_)
814         {
815             this->add_member(
816                 new detail::memfun_registration<T, F, Policies>(
817                     name_, fn, Policies()));
818             return *this;
819         }
820 
821         template<class F, class Default, class Policies>
virtual_defluabind::class_822         class_& virtual_def(char const* name_, F const& fn
823             , Default const& default_, Policies const&, boost::mpl::false_)
824         {
825             this->add_member(
826                 new detail::memfun_registration<T, F, Policies>(
827                     name_, fn, Policies()));
828 
829             this->add_default_member(
830                 new detail::memfun_registration<T, Default, Policies>(
831                     name_, default_, Policies()));
832 
833             return *this;
834         }
835 
836         template<class Signature, class Policies>
def_constructorluabind::class_837         class_& def_constructor(Signature*, Policies const&)
838         {
839             typedef typename Signature::signature signature;
840 
841             typedef typename boost::mpl::if_<
842                 boost::is_same<WrappedType, detail::null_type>
843               , T
844               , WrappedType
845             >::type construct_type;
846 
847             this->add_member(
848                 new detail::constructor_registration<
849                     construct_type, HeldType, signature, Policies>(
850                         Policies()));
851 
852             this->add_default_member(
853                 new detail::constructor_registration<
854                     construct_type, HeldType, signature, Policies>(
855                         Policies()));
856 
857             return *this;
858         }
859     };
860 
861 }
862 
863 #ifdef _MSC_VER
864 #pragma warning(pop)
865 #endif
866 
867 #endif // LUABIND_CLASS_HPP_INCLUDED
868