class.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
  2. // Permission is hereby granted, free of charge, to any person obtaining a
  3. // copy of this software and associated documentation files (the "Software"),
  4. // to deal in the Software without restriction, including without limitation
  5. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  6. // and/or sell copies of the Software, and to permit persons to whom the
  7. // Software is furnished to do so, subject to the following conditions:
  8. // The above copyright notice and this permission notice shall be included
  9. // in all copies or substantial portions of the Software.
  10. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
  11. // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12. // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  14. // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  15. // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  16. // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
  18. // OR OTHER DEALINGS IN THE SOFTWARE.
  19. #ifndef LUABIND_CLASS_HPP_INCLUDED
  20. #define LUABIND_CLASS_HPP_INCLUDED
  21. /*
  22. ISSUES:
  23. ------------------------------------------------------
  24. * solved for member functions, not application operator *
  25. if we have a base class that defines a function a derived class must be able to
  26. override that function (not just overload). Right now we just add the other overload
  27. to the overloads list and will probably get an ambiguity. If we want to support this
  28. each method_rep must include a vector of type_info pointers for each parameter.
  29. Operators do not have this problem, since operators always have to have
  30. it's own type as one of the arguments, no ambiguity can occur. Application
  31. operator, on the other hand, would have this problem.
  32. Properties cannot be overloaded, so they should always be overridden.
  33. If this is to work for application operator, we really need to specify if an application
  34. operator is const or not.
  35. If one class registers two functions with the same name and the same
  36. signature, there's currently no error. The last registered function will
  37. be the one that's used.
  38. How do we know which class registered the function? If the function was
  39. defined by the base class, it is a legal operation, to override it.
  40. we cannot look at the pointer offset, since it always will be zero for one of the bases.
  41. TODO:
  42. ------------------------------------------------------
  43. finish smart pointer support
  44. * the adopt policy should not be able to adopt pointers to held_types. This
  45. must be prohibited.
  46. * name_of_type must recognize holder_types and not return "custom"
  47. document custom policies, custom converters
  48. store the instance object for policies.
  49. support the __concat metamethod. This is a bit tricky, since it cannot be
  50. treated as a normal operator. It is a binary operator but we want to use the
  51. __tostring implementation for both arguments.
  52. */
  53. #include <luabind/prefix.hpp>
  54. #include <luabind/config.hpp>
  55. #include <string>
  56. #include <cassert>
  57. #ifndef LUABIND_CPP0x
  58. #include <boost/preprocessor/repetition/enum_params.hpp>
  59. #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
  60. #include <boost/preprocessor/repetition/repeat.hpp>
  61. #endif
  62. #include <boost/type_traits/is_same.hpp>
  63. #include <boost/type_traits/is_member_object_pointer.hpp>
  64. #include <boost/mpl/apply.hpp>
  65. #include <boost/mpl/lambda.hpp>
  66. #include <boost/mpl/logical.hpp>
  67. #include <boost/mpl/find_if.hpp>
  68. #include <boost/mpl/eval_if.hpp>
  69. #include <boost/mpl/logical.hpp>
  70. #include <boost/mpl/vector/vector10.hpp>
  71. #include <luabind/config.hpp>
  72. #include <luabind/scope.hpp>
  73. #include <luabind/back_reference.hpp>
  74. #include <luabind/function.hpp>
  75. #include <luabind/dependency_policy.hpp>
  76. #include <luabind/detail/constructor.hpp>
  77. #include <luabind/detail/call.hpp>
  78. #include <luabind/detail/deduce_signature.hpp>
  79. #include <luabind/detail/primitives.hpp>
  80. #include <luabind/detail/property.hpp>
  81. #include <luabind/detail/typetraits.hpp>
  82. #include <luabind/detail/class_rep.hpp>
  83. #include <luabind/detail/call.hpp>
  84. #include <luabind/detail/object_rep.hpp>
  85. #include <luabind/detail/call_member.hpp>
  86. #include <luabind/detail/enum_maker.hpp>
  87. #include <luabind/detail/operator_id.hpp>
  88. #include <luabind/detail/pointee_typeid.hpp>
  89. #include <luabind/detail/link_compatibility.hpp>
  90. #include <luabind/detail/inheritance.hpp>
  91. #include <luabind/detail/signature_match.hpp>
  92. #include <luabind/no_dependency.hpp>
  93. #include <luabind/typeid.hpp>
  94. // to remove the 'this' used in initialization list-warning
  95. #ifdef _MSC_VER
  96. #pragma warning(push)
  97. #pragma warning(disable: 4355)
  98. #endif
  99. namespace boost
  100. {
  101. template <class T> class shared_ptr;
  102. } // namespace boost
  103. namespace luabind
  104. {
  105. namespace detail
  106. {
  107. struct unspecified {};
  108. template<class Derived> struct operator_;
  109. struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {};
  110. }
  111. template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
  112. struct class_;
  113. // TODO: this function will only be invoked if the user hasn't defined a correct overload
  114. // maybe we should have a static assert in here?
  115. inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr*
  116. get_const_holder(...)
  117. {
  118. return 0;
  119. }
  120. template <class T>
  121. boost::shared_ptr<T const>* get_const_holder(boost::shared_ptr<T>*)
  122. {
  123. return 0;
  124. }
  125. # ifdef LUABIND_CPP0x
  126. template <class... Args>
  127. struct bases
  128. {};
  129. typedef bases<> no_bases;
  130. # else
  131. template <
  132. BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
  133. LUABIND_MAX_BASES, class A, detail::null_type)
  134. >
  135. struct bases
  136. {};
  137. typedef bases<detail::null_type> no_bases;
  138. # endif // LUABIND_CPP0x
  139. namespace detail
  140. {
  141. template <class T>
  142. struct is_bases
  143. : mpl::false_
  144. {};
  145. # ifdef LUABIND_CPP0x
  146. template <class... Args>
  147. struct is_bases<bases<Args...> >
  148. : mpl::true_
  149. {};
  150. # else
  151. template <BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
  152. struct is_bases<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)> >
  153. : mpl::true_
  154. {};
  155. # endif
  156. template <class T, class P>
  157. struct is_unspecified
  158. : mpl::apply1<P, T>
  159. {};
  160. template <class P>
  161. struct is_unspecified<unspecified, P>
  162. : mpl::true_
  163. {};
  164. template <class P>
  165. struct is_unspecified_mfn
  166. {
  167. template <class T>
  168. struct apply
  169. : is_unspecified<T, P>
  170. {};
  171. };
  172. template<class Predicate>
  173. struct get_predicate
  174. {
  175. typedef mpl::protect<is_unspecified_mfn<Predicate> > type;
  176. };
  177. template <class Result, class Default>
  178. struct result_or_default
  179. {
  180. typedef Result type;
  181. };
  182. template <class Default>
  183. struct result_or_default<unspecified, Default>
  184. {
  185. typedef Default type;
  186. };
  187. template<class Parameters, class Predicate, class DefaultValue>
  188. struct extract_parameter
  189. {
  190. typedef typename get_predicate<Predicate>::type pred;
  191. typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
  192. typedef typename result_or_default<
  193. typename iterator::type, DefaultValue
  194. >::type type;
  195. };
  196. // prints the types of the values on the stack, in the
  197. // range [start_index, lua_gettop()]
  198. LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
  199. struct LUABIND_API create_class
  200. {
  201. static int stage1(lua_State* L);
  202. static int stage2(lua_State* L);
  203. };
  204. } // detail
  205. namespace detail {
  206. template<class T>
  207. struct static_scope
  208. {
  209. static_scope(T& self_) : self(self_)
  210. {
  211. }
  212. T& operator[](scope s) const
  213. {
  214. self.add_inner_scope(s);
  215. return self;
  216. }
  217. private:
  218. template<class U> void operator,(U const&) const;
  219. void operator=(static_scope const&);
  220. T& self;
  221. };
  222. struct class_registration;
  223. struct LUABIND_API class_base : scope
  224. {
  225. public:
  226. class_base(char const* name);
  227. struct base_desc
  228. {
  229. type_id type;
  230. int ptr_offset;
  231. };
  232. void init(
  233. type_id const& type, class_id id
  234. , type_id const& wrapped_type, class_id wrapper_id);
  235. void add_base(type_id const& base, cast_function cast);
  236. void add_member(registration* member);
  237. void add_default_member(registration* member);
  238. const char* name() const;
  239. void add_static_constant(const char* name, int val);
  240. void add_inner_scope(scope& s);
  241. void add_cast(class_id src, class_id target, cast_function cast);
  242. private:
  243. class_registration* m_registration;
  244. };
  245. // MSVC complains about member being sensitive to alignment (C4121)
  246. // when F is a pointer to member of a class with virtual bases.
  247. # ifdef BOOST_MSVC
  248. # pragma pack(push)
  249. # pragma pack(16)
  250. # endif
  251. template <class Class, class F, class Policies>
  252. struct memfun_registration : registration
  253. {
  254. memfun_registration(char const* name, F f, Policies const& policies)
  255. : name(name)
  256. , f(f)
  257. , policies(policies)
  258. {}
  259. void register_(lua_State* L) const
  260. {
  261. object fn = make_function(
  262. L, f, deduce_signature(f, (Class*)0), policies);
  263. add_overload(
  264. object(from_stack(L, -1))
  265. , name
  266. , fn
  267. );
  268. }
  269. char const* name;
  270. F f;
  271. Policies policies;
  272. };
  273. # ifdef BOOST_MSVC
  274. # pragma pack(pop)
  275. # endif
  276. template <class P, class T>
  277. struct default_pointer
  278. {
  279. typedef P type;
  280. };
  281. template <class T>
  282. struct default_pointer<null_type, T>
  283. {
  284. typedef std::auto_ptr<T> type;
  285. };
  286. template <class Class, class Pointer, class Signature, class Policies>
  287. struct constructor_registration : registration
  288. {
  289. constructor_registration(Policies const& policies)
  290. : policies(policies)
  291. {}
  292. void register_(lua_State* L) const
  293. {
  294. typedef typename default_pointer<Pointer, Class>::type pointer;
  295. object fn = make_function(
  296. L
  297. , construct<Class, pointer, Signature>(), Signature()
  298. , policies
  299. );
  300. add_overload(
  301. object(from_stack(L, -1))
  302. , "__init"
  303. , fn
  304. );
  305. }
  306. Policies policies;
  307. };
  308. template <class T>
  309. struct reference_result
  310. : mpl::if_<
  311. mpl::or_<boost::is_pointer<T>, is_primitive<T> >
  312. , T
  313. , typename boost::add_reference<T>::type
  314. >
  315. {};
  316. template <class T>
  317. struct reference_argument
  318. : mpl::if_<
  319. mpl::or_<boost::is_pointer<T>, is_primitive<T> >
  320. , T
  321. , typename boost::add_reference<
  322. typename boost::add_const<T>::type
  323. >::type
  324. >
  325. {};
  326. template <class T, class Policies>
  327. struct inject_dependency_policy
  328. : mpl::if_<
  329. mpl::or_<
  330. is_primitive<T>
  331. , has_policy<Policies, detail::no_dependency_policy>
  332. >
  333. , Policies
  334. , policy_cons<dependency_policy<0, 1>, Policies>
  335. >
  336. {};
  337. template <
  338. class Class
  339. , class Get, class GetPolicies
  340. , class Set = null_type, class SetPolicies = null_type
  341. >
  342. struct property_registration : registration
  343. {
  344. property_registration(
  345. char const* name
  346. , Get const& get
  347. , GetPolicies const& get_policies
  348. , Set const& set = Set()
  349. , SetPolicies const& set_policies = SetPolicies()
  350. )
  351. : name(name)
  352. , get(get)
  353. , get_policies(get_policies)
  354. , set(set)
  355. , set_policies(set_policies)
  356. {}
  357. void register_(lua_State* L) const
  358. {
  359. object context(from_stack(L, -1));
  360. register_aux(
  361. L
  362. , context
  363. , make_get(L, get, boost::is_member_object_pointer<Get>())
  364. , set
  365. );
  366. }
  367. template <class F>
  368. object make_get(lua_State* L, F const& f, mpl::false_) const
  369. {
  370. return make_function(
  371. L, f, deduce_signature(f, (Class*)0), get_policies);
  372. }
  373. template <class T, class D>
  374. object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const
  375. {
  376. typedef typename reference_result<D>::type result_type;
  377. typedef typename inject_dependency_policy<
  378. D, GetPolicies>::type policies;
  379. return make_function(
  380. L
  381. , access_member_ptr<T, D, result_type>(mem_ptr)
  382. , mpl::vector2<result_type, Class const&>()
  383. , policies()
  384. );
  385. }
  386. template <class F>
  387. object make_set(lua_State* L, F const& f, mpl::false_) const
  388. {
  389. return make_function(
  390. L, f, deduce_signature(f, (Class*)0), set_policies);
  391. }
  392. template <class T, class D>
  393. object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const
  394. {
  395. typedef typename reference_argument<D>::type argument_type;
  396. return make_function(
  397. L
  398. , access_member_ptr<T, D>(mem_ptr)
  399. , mpl::vector3<void, Class&, argument_type>()
  400. , set_policies
  401. );
  402. }
  403. template <class S>
  404. void register_aux(
  405. lua_State* L, object const& context
  406. , object const& get_, S const&) const
  407. {
  408. context[name] = property(
  409. get_
  410. , make_set(L, set, boost::is_member_object_pointer<Set>())
  411. );
  412. }
  413. void register_aux(
  414. lua_State*, object const& context
  415. , object const& get_, null_type) const
  416. {
  417. context[name] = property(get_);
  418. }
  419. char const* name;
  420. Get get;
  421. GetPolicies get_policies;
  422. Set set;
  423. SetPolicies set_policies;
  424. };
  425. } // namespace detail
  426. // registers a class in the lua environment
  427. template<class T, class X1, class X2, class X3>
  428. struct class_: detail::class_base
  429. {
  430. typedef class_<T, X1, X2, X3> self_t;
  431. private:
  432. template<class A, class B, class C, class D>
  433. class_(const class_<A,B,C,D>&);
  434. public:
  435. typedef boost::mpl::vector4<X1, X2, X3, detail::unspecified> parameters_type;
  436. // WrappedType MUST inherit from T
  437. typedef typename detail::extract_parameter<
  438. parameters_type
  439. , boost::is_base_and_derived<T, boost::mpl::_>
  440. , detail::null_type
  441. >::type WrappedType;
  442. typedef typename detail::extract_parameter<
  443. parameters_type
  444. , boost::mpl::not_<
  445. boost::mpl::or_<
  446. detail::is_bases<boost::mpl::_>
  447. , boost::is_base_and_derived<boost::mpl::_, T>
  448. , boost::is_base_and_derived<T, boost::mpl::_>
  449. >
  450. >
  451. , detail::null_type
  452. >::type HeldType;
  453. template <class Src, class Target>
  454. void add_downcast(Src*, Target*, boost::mpl::true_)
  455. {
  456. add_cast(
  457. detail::registered_class<Src>::id
  458. , detail::registered_class<Target>::id
  459. , detail::dynamic_cast_<Src, Target>::execute
  460. );
  461. }
  462. template <class Src, class Target>
  463. void add_downcast(Src*, Target*, boost::mpl::false_)
  464. {}
  465. // this function generates conversion information
  466. // in the given class_rep structure. It will be able
  467. // to implicitly cast to the given template type
  468. template<class To>
  469. void gen_base_info(detail::type_<To>)
  470. {
  471. add_base(typeid(To), detail::static_cast_<T, To>::execute);
  472. add_cast(
  473. detail::registered_class<T>::id
  474. , detail::registered_class<To>::id
  475. , detail::static_cast_<T, To>::execute
  476. );
  477. add_downcast((To*)0, (T*)0, boost::is_polymorphic<To>());
  478. }
  479. void gen_base_info(detail::type_<detail::null_type>)
  480. {}
  481. # ifndef LUABIND_CPP0x
  482. #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_<BaseClass##n>());
  483. template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class BaseClass)>
  484. void generate_baseclass_list(detail::type_<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, BaseClass)> >)
  485. {
  486. BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
  487. }
  488. #undef LUABIND_GEN_BASE_INFO
  489. # else // !LUABIND_CPP0x
  490. template <class... Args>
  491. void ignore(Args&&...)
  492. {}
  493. template <class... Bases>
  494. void generate_baseclass_list(detail::type_<bases<Bases...> >)
  495. {
  496. ignore((gen_base_info(detail::type_<Bases>()), 0)...);
  497. }
  498. # endif // !LUABIND_CPP0x
  499. class_(const char* name): class_base(name), scope(*this)
  500. {
  501. #ifndef NDEBUG
  502. detail::check_link_compatibility();
  503. #endif
  504. init();
  505. }
  506. template<class F>
  507. class_& def(const char* name, F f)
  508. {
  509. return this->virtual_def(
  510. name, f, detail::null_type()
  511. , detail::null_type(), boost::mpl::true_());
  512. }
  513. // virtual functions
  514. template<class F, class DefaultOrPolicies>
  515. class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies)
  516. {
  517. return this->virtual_def(
  518. name, fn, default_or_policies, detail::null_type()
  519. , LUABIND_MSVC_TYPENAME detail::is_policy_cons<DefaultOrPolicies>::type());
  520. }
  521. template<class F, class Default, class Policies>
  522. class_& def(char const* name, F fn
  523. , Default default_, Policies const& policies)
  524. {
  525. return this->virtual_def(
  526. name, fn, default_
  527. , policies, boost::mpl::false_());
  528. }
  529. # ifdef LUABIND_CPP0x
  530. template <class... Args, class Policies = detail::null_type>
  531. class_& def(constructor<Args...>, Policies const& policies = Policies())
  532. {
  533. return this->def_constructor((constructor<Args...>*)0, policies);
  534. }
  535. # else
  536. template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
  537. class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
  538. {
  539. return this->def_constructor(&sig, detail::null_type());
  540. }
  541. template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
  542. class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
  543. {
  544. return this->def_constructor(&sig, policies);
  545. }
  546. # endif // LUABIND_CPP0x
  547. template <class Getter>
  548. class_& property(const char* name, Getter g)
  549. {
  550. this->add_member(
  551. new detail::property_registration<T, Getter, detail::null_type>(
  552. name, g, detail::null_type()));
  553. return *this;
  554. }
  555. template <class Getter, class MaybeSetter>
  556. class_& property(const char* name, Getter g, MaybeSetter s)
  557. {
  558. return property_impl(
  559. name, g, s
  560. , boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>()
  561. );
  562. }
  563. template<class Getter, class Setter, class GetPolicies>
  564. class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
  565. {
  566. typedef detail::property_registration<
  567. T, Getter, GetPolicies, Setter, detail::null_type
  568. > registration_type;
  569. this->add_member(
  570. new registration_type(name, g, get_policies, s));
  571. return *this;
  572. }
  573. template<class Getter, class Setter, class GetPolicies, class SetPolicies>
  574. class_& property(
  575. const char* name
  576. , Getter g, Setter s
  577. , GetPolicies const& get_policies
  578. , SetPolicies const& set_policies)
  579. {
  580. typedef detail::property_registration<
  581. T, Getter, GetPolicies, Setter, SetPolicies
  582. > registration_type;
  583. this->add_member(
  584. new registration_type(name, g, get_policies, s, set_policies));
  585. return *this;
  586. }
  587. template <class C, class D>
  588. class_& def_readonly(const char* name, D C::*mem_ptr)
  589. {
  590. typedef detail::property_registration<T, D C::*, detail::null_type>
  591. registration_type;
  592. this->add_member(
  593. new registration_type(name, mem_ptr, detail::null_type()));
  594. return *this;
  595. }
  596. template <class C, class D, class Policies>
  597. class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies)
  598. {
  599. typedef detail::property_registration<T, D C::*, Policies>
  600. registration_type;
  601. this->add_member(
  602. new registration_type(name, mem_ptr, policies));
  603. return *this;
  604. }
  605. template <class C, class D>
  606. class_& def_readwrite(const char* name, D C::*mem_ptr)
  607. {
  608. typedef detail::property_registration<
  609. T, D C::*, detail::null_type, D C::*
  610. > registration_type;
  611. this->add_member(
  612. new registration_type(
  613. name, mem_ptr, detail::null_type(), mem_ptr));
  614. return *this;
  615. }
  616. template <class C, class D, class GetPolicies>
  617. class_& def_readwrite(
  618. const char* name, D C::*mem_ptr, GetPolicies const& get_policies)
  619. {
  620. typedef detail::property_registration<
  621. T, D C::*, GetPolicies, D C::*
  622. > registration_type;
  623. this->add_member(
  624. new registration_type(
  625. name, mem_ptr, get_policies, mem_ptr));
  626. return *this;
  627. }
  628. template <class C, class D, class GetPolicies, class SetPolicies>
  629. class_& def_readwrite(
  630. const char* name
  631. , D C::*mem_ptr
  632. , GetPolicies const& get_policies
  633. , SetPolicies const& set_policies
  634. )
  635. {
  636. typedef detail::property_registration<
  637. T, D C::*, GetPolicies, D C::*, SetPolicies
  638. > registration_type;
  639. this->add_member(
  640. new registration_type(
  641. name, mem_ptr, get_policies, mem_ptr, set_policies));
  642. return *this;
  643. }
  644. template<class Derived, class Policies>
  645. class_& def(detail::operator_<Derived>, Policies const& policies)
  646. {
  647. return this->def(
  648. Derived::name()
  649. , &Derived::template apply<T, Policies>::execute
  650. , policies
  651. );
  652. }
  653. template<class Derived>
  654. class_& def(detail::operator_<Derived>)
  655. {
  656. return this->def(
  657. Derived::name()
  658. , &Derived::template apply<T, detail::null_type>::execute
  659. );
  660. }
  661. detail::enum_maker<self_t> enum_(const char*)
  662. {
  663. return detail::enum_maker<self_t>(*this);
  664. }
  665. detail::static_scope<self_t> scope;
  666. private:
  667. void operator=(class_ const&);
  668. void add_wrapper_cast(detail::null_type*)
  669. {}
  670. template <class U>
  671. void add_wrapper_cast(U*)
  672. {
  673. add_cast(
  674. detail::registered_class<U>::id
  675. , detail::registered_class<T>::id
  676. , detail::static_cast_<U,T>::execute
  677. );
  678. add_downcast((T*)0, (U*)0, boost::is_polymorphic<T>());
  679. }
  680. void init()
  681. {
  682. typedef typename detail::extract_parameter<
  683. parameters_type
  684. , boost::mpl::or_<
  685. detail::is_bases<boost::mpl::_>
  686. , boost::is_base_and_derived<boost::mpl::_, T>
  687. >
  688. , no_bases
  689. >::type bases_t;
  690. typedef typename
  691. boost::mpl::if_<detail::is_bases<bases_t>
  692. , bases_t
  693. , bases<bases_t>
  694. >::type Base;
  695. class_base::init(
  696. typeid(T)
  697. , detail::registered_class<T>::id
  698. , typeid(WrappedType)
  699. , detail::registered_class<WrappedType>::id
  700. );
  701. add_wrapper_cast((WrappedType*)0);
  702. generate_baseclass_list(detail::type_<Base>());
  703. }
  704. template<class Getter, class GetPolicies>
  705. class_& property_impl(const char* name,
  706. Getter g,
  707. GetPolicies policies,
  708. boost::mpl::bool_<true>)
  709. {
  710. this->add_member(
  711. new detail::property_registration<T, Getter, GetPolicies>(
  712. name, g, policies));
  713. return *this;
  714. }
  715. template<class Getter, class Setter>
  716. class_& property_impl(const char* name,
  717. Getter g,
  718. Setter s,
  719. boost::mpl::bool_<false>)
  720. {
  721. typedef detail::property_registration<
  722. T, Getter, detail::null_type, Setter, detail::null_type
  723. > registration_type;
  724. this->add_member(
  725. new registration_type(name, g, detail::null_type(), s));
  726. return *this;
  727. }
  728. // these handle default implementation of virtual functions
  729. template<class F, class Policies>
  730. class_& virtual_def(char const* name, F const& fn
  731. , Policies const&, detail::null_type, boost::mpl::true_)
  732. {
  733. this->add_member(
  734. new detail::memfun_registration<T, F, Policies>(
  735. name, fn, Policies()));
  736. return *this;
  737. }
  738. template<class F, class Default, class Policies>
  739. class_& virtual_def(char const* name, F const& fn
  740. , Default const& default_, Policies const&, boost::mpl::false_)
  741. {
  742. this->add_member(
  743. new detail::memfun_registration<T, F, Policies>(
  744. name, fn, Policies()));
  745. this->add_default_member(
  746. new detail::memfun_registration<T, Default, Policies>(
  747. name, default_, Policies()));
  748. return *this;
  749. }
  750. template<class Signature, class Policies>
  751. class_& def_constructor(Signature*, Policies const&)
  752. {
  753. typedef typename Signature::signature signature;
  754. typedef typename boost::mpl::if_<
  755. boost::is_same<WrappedType, detail::null_type>
  756. , T
  757. , WrappedType
  758. >::type construct_type;
  759. this->add_member(
  760. new detail::constructor_registration<
  761. construct_type, HeldType, signature, Policies>(
  762. Policies()));
  763. this->add_default_member(
  764. new detail::constructor_registration<
  765. construct_type, HeldType, signature, Policies>(
  766. Policies()));
  767. return *this;
  768. }
  769. };
  770. }
  771. #ifdef _MSC_VER
  772. #pragma warning(pop)
  773. #endif
  774. #endif // LUABIND_CLASS_HPP_INCLUDED