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