object.hpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
  1. // Copyright (c) 2005 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_OBJECT_050419_HPP
  20. #define LUABIND_OBJECT_050419_HPP
  21. #include <boost/implicit_cast.hpp> // detail::push()
  22. #include <boost/ref.hpp> // detail::push()
  23. #include <boost/mpl/bool.hpp> // value_wrapper_traits specializations
  24. #include <boost/mpl/apply_wrap.hpp>
  25. #ifdef LUABIND_CPP0x
  26. # include <tuple>
  27. #else
  28. # include <boost/tuple/tuple.hpp>
  29. #endif
  30. #include <boost/optional.hpp>
  31. #include <luabind/nil.hpp>
  32. #include <luabind/value_wrapper.hpp>
  33. #include <luabind/detail/pcall.hpp>
  34. #include <luabind/handle.hpp>
  35. #include <luabind/from_stack.hpp>
  36. #include <luabind/detail/policy.hpp>
  37. #include <luabind/detail/stack_utils.hpp>
  38. #include <luabind/detail/convert_to_lua.hpp> // REFACTOR
  39. #include <luabind/typeid.hpp>
  40. #include <boost/iterator/iterator_facade.hpp> // iterator
  41. #ifndef LUABIND_CPP0x
  42. #include <boost/preprocessor/iteration/iterate.hpp>
  43. #endif
  44. #include <boost/utility/enable_if.hpp>
  45. namespace luabind {
  46. namespace detail
  47. {
  48. namespace mpl = boost::mpl;
  49. template<class T, class ConverterGenerator>
  50. void push_aux(lua_State* interpreter, T& value, ConverterGenerator*)
  51. {
  52. typedef typename boost::mpl::if_<
  53. boost::is_reference_wrapper<T>
  54. , BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
  55. , T
  56. >::type unwrapped_type;
  57. typename mpl::apply_wrap2<
  58. ConverterGenerator,unwrapped_type,cpp_to_lua
  59. >::type cv;
  60. cv.apply(
  61. interpreter
  62. , boost::implicit_cast<
  63. BOOST_DEDUCED_TYPENAME boost::unwrap_reference<T>::type&
  64. >(value)
  65. );
  66. }
  67. template<class T, class Policies>
  68. void push(lua_State* interpreter, T& value, Policies const&)
  69. {
  70. typedef typename find_conversion_policy<
  71. 0
  72. , Policies
  73. >::type converter_policy;
  74. push_aux(interpreter, value, (converter_policy*)0);
  75. }
  76. template<class T>
  77. void push(lua_State* interpreter, T& value)
  78. {
  79. push(interpreter, value, null_type());
  80. }
  81. } // namespace detail
  82. namespace adl
  83. {
  84. namespace mpl = boost::mpl;
  85. template <class T>
  86. class object_interface;
  87. namespace is_object_interface_aux
  88. {
  89. typedef char (&yes)[1];
  90. typedef char (&no)[2];
  91. template <class T>
  92. yes check(object_interface<T>*);
  93. no check(void*);
  94. template <class T>
  95. struct impl
  96. {
  97. BOOST_STATIC_CONSTANT(bool, value =
  98. sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes)
  99. );
  100. typedef mpl::bool_<value> type;
  101. };
  102. } // namespace detail
  103. template <class T>
  104. struct is_object_interface
  105. : is_object_interface_aux::impl<T>::type
  106. {};
  107. template <class R, class T, class U>
  108. struct enable_binary
  109. # ifndef BOOST_NO_SFINAE
  110. : boost::enable_if<
  111. mpl::or_<
  112. is_object_interface<T>
  113. , is_object_interface<U>
  114. >
  115. , R
  116. >
  117. {};
  118. # else
  119. {
  120. typedef R type;
  121. };
  122. # endif
  123. template<class T, class U>
  124. int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs
  125. , boost::mpl::true_, boost::mpl::true_)
  126. {
  127. L = value_wrapper_traits<T>::interpreter(lhs);
  128. lua_State* L2 = value_wrapper_traits<U>::interpreter(rhs);
  129. // you are comparing objects with different interpreters
  130. // that's not allowed.
  131. assert(L == L2 || L == 0 || L2 == 0);
  132. // if the two objects we compare have different interpreters
  133. // then they
  134. if (L != L2) return -1;
  135. if (L == 0) return 1;
  136. return 0;
  137. }
  138. template<class T, class U>
  139. int binary_interpreter(lua_State*& L, T const& x, U const&
  140. , boost::mpl::true_, boost::mpl::false_)
  141. {
  142. L = value_wrapper_traits<T>::interpreter(x);
  143. return 0;
  144. }
  145. template<class T, class U>
  146. int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_)
  147. {
  148. L = value_wrapper_traits<U>::interpreter(x);
  149. return 0;
  150. }
  151. template<class T, class U>
  152. int binary_interpreter(lua_State*& L, T const& x, U const& y)
  153. {
  154. return binary_interpreter(
  155. L
  156. , x
  157. , y
  158. , is_value_wrapper<T>()
  159. , is_value_wrapper<U>()
  160. );
  161. }
  162. #define LUABIND_BINARY_OP_DEF(op, fn) \
  163. template<class LHS, class RHS> \
  164. typename enable_binary<bool,LHS,RHS>::type \
  165. operator op(LHS const& lhs, RHS const& rhs) \
  166. { \
  167. lua_State* L = 0; \
  168. switch (binary_interpreter(L, lhs, rhs)) \
  169. { \
  170. case 1: \
  171. return true; \
  172. case -1: \
  173. return false; \
  174. } \
  175. \
  176. assert(L); \
  177. \
  178. detail::stack_pop pop1(L, 1); \
  179. detail::push(L, lhs); \
  180. detail::stack_pop pop2(L, 1); \
  181. detail::push(L, rhs); \
  182. \
  183. return fn(L, -1, -2) != 0; \
  184. }
  185. LUABIND_BINARY_OP_DEF(==, lua_equal)
  186. LUABIND_BINARY_OP_DEF(<, lua_lessthan)
  187. template<class ValueWrapper>
  188. std::ostream& operator<<(std::ostream& os
  189. , object_interface<ValueWrapper> const& v)
  190. {
  191. using namespace luabind;
  192. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  193. static_cast<ValueWrapper const&>(v));
  194. detail::stack_pop pop(interpreter, 1);
  195. value_wrapper_traits<ValueWrapper>::unwrap(interpreter
  196. , static_cast<ValueWrapper const&>(v));
  197. char const* p = lua_tostring(interpreter, -1);
  198. std::size_t len = lua_strlen(interpreter, -1);
  199. std::copy(p, p + len, std::ostream_iterator<char>(os));
  200. return os;
  201. }
  202. #undef LUABIND_BINARY_OP_DEF
  203. template<class LHS, class RHS>
  204. typename enable_binary<bool,LHS,RHS>::type
  205. operator>(LHS const& lhs, RHS const& rhs)
  206. {
  207. return !(lhs < rhs || lhs == rhs);
  208. }
  209. template<class LHS, class RHS>
  210. typename enable_binary<bool,LHS,RHS>::type
  211. operator<=(LHS const& lhs, RHS const& rhs)
  212. {
  213. return lhs < rhs || lhs == rhs;
  214. }
  215. template<class LHS, class RHS>
  216. typename enable_binary<bool,LHS,RHS>::type
  217. operator>=(LHS const& lhs, RHS const& rhs)
  218. {
  219. return !(lhs < rhs);
  220. }
  221. template<class LHS, class RHS>
  222. typename enable_binary<bool,LHS,RHS>::type
  223. operator!=(LHS const& lhs, RHS const& rhs)
  224. {
  225. return !(lhs == rhs);
  226. }
  227. template<class ValueWrapper, class Arguments>
  228. struct call_proxy;
  229. template<class Next>
  230. class index_proxy;
  231. class object;
  232. template<class Derived>
  233. class object_interface
  234. {
  235. struct safe_bool_type {};
  236. public:
  237. ~object_interface() {}
  238. # ifdef LUABIND_CPP0x
  239. template <class... Args>
  240. call_proxy<
  241. Derived, std::tuple<Args const*...>
  242. > operator()(Args const& ...args)
  243. {
  244. typedef std::tuple<Args const*...> arguments;
  245. return call_proxy<Derived, arguments>(derived(), arguments(&args...));
  246. }
  247. # else
  248. call_proxy<Derived, boost::tuples::tuple<> > operator()();
  249. template<class A0>
  250. call_proxy<
  251. Derived
  252. , boost::tuples::tuple<A0 const*>
  253. > operator()(A0 const& a0)
  254. {
  255. typedef boost::tuples::tuple<A0 const*> arguments;
  256. return call_proxy<Derived, arguments>(
  257. derived()
  258. , arguments(&a0)
  259. );
  260. }
  261. template<class A0, class A1>
  262. call_proxy<
  263. Derived
  264. , boost::tuples::tuple<A0 const*, A1 const*>
  265. > operator()(A0 const& a0, A1 const& a1)
  266. {
  267. typedef boost::tuples::tuple<A0 const*, A1 const*> arguments;
  268. return call_proxy<Derived, arguments>(
  269. derived()
  270. , arguments(&a0, &a1)
  271. );
  272. }
  273. // The rest of the overloads are PP-generated.
  274. #define BOOST_PP_ITERATION_PARAMS_1 (3, \
  275. (3, LUABIND_MAX_ARITY, <luabind/detail/object_call.hpp>))
  276. #include BOOST_PP_ITERATE()
  277. # endif // LUABIND_CPP0x
  278. operator safe_bool_type*() const
  279. {
  280. lua_State* L = value_wrapper_traits<Derived>::interpreter(derived());
  281. if (!L)
  282. return 0;
  283. value_wrapper_traits<Derived>::unwrap(L, derived());
  284. detail::stack_pop pop(L, 1);
  285. return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0;
  286. }
  287. private:
  288. Derived& derived()
  289. {
  290. return *static_cast<Derived*>(this);
  291. }
  292. Derived const& derived() const
  293. {
  294. return *static_cast<Derived const*>(this);
  295. }
  296. };
  297. #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
  298. struct iterator_proxy_tag;
  299. #endif
  300. template<class AccessPolicy>
  301. class iterator_proxy
  302. : public object_interface<iterator_proxy<AccessPolicy> >
  303. {
  304. public:
  305. #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
  306. typedef iterator_proxy_tag value_wrapper_tag;
  307. #endif
  308. iterator_proxy(lua_State* interpreter, handle const& table, handle const& key)
  309. : m_interpreter(interpreter)
  310. , m_table_index(lua_gettop(interpreter) + 1)
  311. , m_key_index(m_table_index + 1)
  312. {
  313. table.push(m_interpreter);
  314. key.push(m_interpreter);
  315. }
  316. iterator_proxy(iterator_proxy const& other)
  317. : m_interpreter(other.m_interpreter)
  318. , m_table_index(other.m_table_index)
  319. , m_key_index(other.m_key_index)
  320. {
  321. other.m_interpreter = 0;
  322. }
  323. ~iterator_proxy()
  324. {
  325. if (m_interpreter)
  326. lua_pop(m_interpreter, 2);
  327. }
  328. // this will set the value to nil
  329. iterator_proxy & operator=(luabind::detail::nil_type)
  330. {
  331. lua_pushvalue(m_interpreter, m_key_index);
  332. lua_pushnil(m_interpreter);
  333. AccessPolicy::set(m_interpreter, m_table_index);
  334. return *this;
  335. }
  336. template<class T>
  337. iterator_proxy& operator=(T const& value)
  338. {
  339. lua_pushvalue(m_interpreter, m_key_index);
  340. detail::push(m_interpreter, value);
  341. AccessPolicy::set(m_interpreter, m_table_index);
  342. return *this;
  343. }
  344. template<class Key>
  345. index_proxy<iterator_proxy<AccessPolicy> > operator[](Key const& key)
  346. {
  347. return index_proxy<iterator_proxy<AccessPolicy> >(
  348. *this, m_interpreter, key
  349. );
  350. }
  351. // This is non-const to prevent conversion on lvalues.
  352. operator object();
  353. lua_State* interpreter() const
  354. {
  355. return m_interpreter;
  356. }
  357. // TODO: Why is it non-const?
  358. void push(lua_State* interpreter)
  359. {
  360. assert(interpreter == m_interpreter);
  361. lua_pushvalue(m_interpreter, m_key_index);
  362. AccessPolicy::get(m_interpreter, m_table_index);
  363. }
  364. private:
  365. mutable lua_State* m_interpreter;
  366. int m_table_index;
  367. int m_key_index;
  368. };
  369. } // namespace adl
  370. namespace detail
  371. {
  372. struct basic_access
  373. {
  374. static void set(lua_State* interpreter, int table)
  375. {
  376. lua_settable(interpreter, table);
  377. }
  378. static void get(lua_State* interpreter, int table)
  379. {
  380. lua_gettable(interpreter, table);
  381. }
  382. };
  383. struct raw_access
  384. {
  385. static void set(lua_State* interpreter, int table)
  386. {
  387. lua_rawset(interpreter, table);
  388. }
  389. static void get(lua_State* interpreter, int table)
  390. {
  391. lua_rawget(interpreter, table);
  392. }
  393. };
  394. template<class AccessPolicy>
  395. class basic_iterator
  396. : public boost::iterator_facade<
  397. basic_iterator<AccessPolicy>
  398. , adl::iterator_proxy<AccessPolicy>
  399. , boost::single_pass_traversal_tag
  400. , adl::iterator_proxy<AccessPolicy>
  401. >
  402. {
  403. public:
  404. basic_iterator()
  405. : m_interpreter(0)
  406. {}
  407. template<class ValueWrapper>
  408. explicit basic_iterator(ValueWrapper const& value_wrapper)
  409. : m_interpreter(
  410. value_wrapper_traits<ValueWrapper>::interpreter(value_wrapper)
  411. )
  412. {
  413. detail::stack_pop pop(m_interpreter, 1);
  414. value_wrapper_traits<ValueWrapper>::unwrap(m_interpreter, value_wrapper);
  415. lua_pushnil(m_interpreter);
  416. if (lua_next(m_interpreter, -2) != 0)
  417. {
  418. detail::stack_pop pop(m_interpreter, 2);
  419. handle(m_interpreter, -2).swap(m_key);
  420. }
  421. else
  422. {
  423. m_interpreter = 0;
  424. return;
  425. }
  426. handle(m_interpreter, -1).swap(m_table);
  427. }
  428. adl::object key() const;
  429. private:
  430. friend class boost::iterator_core_access;
  431. void increment()
  432. {
  433. m_table.push(m_interpreter);
  434. m_key.push(m_interpreter);
  435. detail::stack_pop pop(m_interpreter, 1);
  436. if (lua_next(m_interpreter, -2) != 0)
  437. {
  438. m_key.replace(m_interpreter, -2);
  439. lua_pop(m_interpreter, 2);
  440. }
  441. else
  442. {
  443. m_interpreter = 0;
  444. handle().swap(m_table);
  445. handle().swap(m_key);
  446. }
  447. }
  448. bool equal(basic_iterator const& other) const
  449. {
  450. if (m_interpreter == 0 && other.m_interpreter == 0)
  451. return true;
  452. if (m_interpreter != other.m_interpreter)
  453. return false;
  454. detail::stack_pop pop(m_interpreter, 2);
  455. m_key.push(m_interpreter);
  456. other.m_key.push(m_interpreter);
  457. return lua_equal(m_interpreter, -2, -1) != 0;
  458. }
  459. adl::iterator_proxy<AccessPolicy> dereference() const
  460. {
  461. return adl::iterator_proxy<AccessPolicy>(m_interpreter, m_table, m_key);
  462. }
  463. lua_State* m_interpreter;
  464. handle m_table;
  465. handle m_key;
  466. };
  467. // Needed because of some strange ADL issues.
  468. /*#define LUABIND_OPERATOR_ADL_WKND(op) \
  469. inline bool operator op( \
  470. basic_iterator<basic_access> const& x \
  471. , basic_iterator<basic_access> const& y) \
  472. { \
  473. return boost::operator op(x, y); \
  474. } \
  475. \
  476. inline bool operator op( \
  477. basic_iterator<raw_access> const& x \
  478. , basic_iterator<raw_access> const& y) \
  479. { \
  480. return boost::operator op(x, y); \
  481. }
  482. LUABIND_OPERATOR_ADL_WKND(==)
  483. LUABIND_OPERATOR_ADL_WKND(!=)
  484. #undef LUABIND_OPERATOR_ADL_WKND
  485. */
  486. } // namespace detail
  487. namespace adl
  488. {
  489. #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
  490. struct index_proxy_tag;
  491. #endif
  492. template<class Next>
  493. class index_proxy
  494. : public object_interface<index_proxy<Next> >
  495. {
  496. public:
  497. #ifdef LUABIND_USE_VALUE_WRAPPER_TAG
  498. typedef index_proxy_tag value_wrapper_tag;
  499. #endif
  500. typedef index_proxy<Next> this_type;
  501. template<class Key>
  502. index_proxy(Next const& next, lua_State* interpreter, Key const& key)
  503. : m_interpreter(interpreter)
  504. , m_key_index(lua_gettop(interpreter) + 1)
  505. , m_next(next)
  506. {
  507. detail::push(m_interpreter, key);
  508. }
  509. index_proxy(index_proxy const& other)
  510. : m_interpreter(other.m_interpreter)
  511. , m_key_index(other.m_key_index)
  512. , m_next(other.m_next)
  513. {
  514. other.m_interpreter = 0;
  515. }
  516. ~index_proxy()
  517. {
  518. if (m_interpreter)
  519. lua_pop(m_interpreter, 1);
  520. }
  521. // This is non-const to prevent conversion on lvalues.
  522. operator object();
  523. // this will set the value to nil
  524. this_type& operator=(luabind::detail::nil_type)
  525. {
  526. value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
  527. detail::stack_pop pop(m_interpreter, 1);
  528. lua_pushvalue(m_interpreter, m_key_index);
  529. lua_pushnil(m_interpreter);
  530. lua_settable(m_interpreter, -3);
  531. return *this;
  532. }
  533. template<class T>
  534. this_type& operator=(T const& value)
  535. {
  536. value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
  537. detail::stack_pop pop(m_interpreter, 1);
  538. lua_pushvalue(m_interpreter, m_key_index);
  539. detail::push(m_interpreter, value);
  540. lua_settable(m_interpreter, -3);
  541. return *this;
  542. }
  543. this_type& operator=(this_type const& value)
  544. {
  545. value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
  546. detail::stack_pop pop(m_interpreter, 1);
  547. lua_pushvalue(m_interpreter, m_key_index);
  548. detail::push(m_interpreter, value);
  549. lua_settable(m_interpreter, -3);
  550. return *this;
  551. }
  552. template<class T>
  553. index_proxy<this_type> operator[](T const& key)
  554. {
  555. return index_proxy<this_type>(*this, m_interpreter, key);
  556. }
  557. void push(lua_State* interpreter);
  558. lua_State* interpreter() const
  559. {
  560. return m_interpreter;
  561. }
  562. private:
  563. struct hidden_type {};
  564. // this_type& operator=(index_proxy<Next> const&);
  565. mutable lua_State* m_interpreter;
  566. int m_key_index;
  567. Next const& m_next;
  568. };
  569. } // namespace adl
  570. typedef detail::basic_iterator<detail::basic_access> iterator;
  571. typedef detail::basic_iterator<detail::raw_access> raw_iterator;
  572. #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
  573. template<class T>
  574. struct value_wrapper_traits<adl::index_proxy<T> >
  575. #else
  576. template<>
  577. struct value_wrapper_traits<adl::index_proxy_tag>
  578. #endif
  579. {
  580. typedef boost::mpl::true_ is_specialized;
  581. template<class Next>
  582. static lua_State* interpreter(adl::index_proxy<Next> const& proxy)
  583. {
  584. return proxy.interpreter();
  585. }
  586. template<class Next>
  587. static void unwrap(lua_State* interpreter, adl::index_proxy<Next> const& proxy)
  588. {
  589. const_cast<adl::index_proxy<Next>&>(proxy).push(interpreter);
  590. }
  591. };
  592. #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
  593. template<class AccessPolicy>
  594. struct value_wrapper_traits<adl::iterator_proxy<AccessPolicy> >
  595. #else
  596. template<>
  597. struct value_wrapper_traits<adl::iterator_proxy_tag>
  598. #endif
  599. {
  600. typedef boost::mpl::true_ is_specialized;
  601. template<class Proxy>
  602. static lua_State* interpreter(Proxy const& p)
  603. {
  604. return p.interpreter();
  605. }
  606. template<class Proxy>
  607. static void unwrap(lua_State* interpreter, Proxy const& p)
  608. {
  609. // TODO: Why const_cast?
  610. const_cast<Proxy&>(p).push(interpreter);
  611. }
  612. };
  613. namespace adl
  614. {
  615. // An object holds a reference to a Lua value residing
  616. // in the registry.
  617. class object : public object_interface<object>
  618. {
  619. public:
  620. object()
  621. {}
  622. explicit object(handle const& other)
  623. : m_handle(other)
  624. {}
  625. explicit object(from_stack const& stack_reference)
  626. : m_handle(stack_reference.interpreter, stack_reference.index)
  627. {
  628. }
  629. template<class T>
  630. object(lua_State* interpreter, T const& value)
  631. {
  632. detail::push(interpreter, value);
  633. detail::stack_pop pop(interpreter, 1);
  634. handle(interpreter, -1).swap(m_handle);
  635. }
  636. template<class T, class Policies>
  637. object(lua_State* interpreter, T const& value, Policies const&)
  638. {
  639. detail::push(interpreter, value, Policies());
  640. detail::stack_pop pop(interpreter, 1);
  641. handle(interpreter, -1).swap(m_handle);
  642. }
  643. void push(lua_State* interpreter) const;
  644. lua_State* interpreter() const;
  645. bool is_valid() const;
  646. template<class T>
  647. index_proxy<object> operator[](T const& key) const
  648. {
  649. return index_proxy<object>(
  650. *this, m_handle.interpreter(), key
  651. );
  652. }
  653. void swap(object& other)
  654. {
  655. m_handle.swap(other.m_handle);
  656. }
  657. private:
  658. handle m_handle;
  659. };
  660. inline void object::push(lua_State* interpreter) const
  661. {
  662. m_handle.push(interpreter);
  663. }
  664. inline lua_State* object::interpreter() const
  665. {
  666. return m_handle.interpreter();
  667. }
  668. inline bool object::is_valid() const
  669. {
  670. return m_handle.interpreter() != 0;
  671. }
  672. class argument : public object_interface<argument>
  673. {
  674. public:
  675. argument(from_stack const& stack_reference)
  676. : m_interpreter(stack_reference.interpreter)
  677. , m_index(stack_reference.index)
  678. {
  679. if (m_index < 0)
  680. m_index = lua_gettop(m_interpreter) - m_index + 1;
  681. }
  682. template<class T>
  683. index_proxy<argument> operator[](T const& key) const
  684. {
  685. return index_proxy<argument>(*this, m_interpreter, key);
  686. }
  687. void push(lua_State* L) const
  688. {
  689. lua_pushvalue(L, m_index);
  690. }
  691. lua_State* interpreter() const
  692. {
  693. return m_interpreter;
  694. }
  695. private:
  696. lua_State* m_interpreter;
  697. int m_index;
  698. };
  699. } // namespace adl
  700. using adl::object;
  701. using adl::argument;
  702. #ifndef LUABIND_USE_VALUE_WRAPPER_TAG
  703. template <class ValueWrapper, class Arguments>
  704. struct value_wrapper_traits<adl::call_proxy<ValueWrapper, Arguments> >
  705. #else
  706. template<>
  707. struct value_wrapper_traits<adl::call_proxy_tag>
  708. #endif
  709. {
  710. typedef boost::mpl::true_ is_specialized;
  711. template<class W, class A>
  712. static lua_State* interpreter(adl::call_proxy<W,A> const& proxy)
  713. {
  714. return value_wrapper_traits<W>::interpreter(*proxy.value_wrapper);
  715. }
  716. template<class W, class A>
  717. static void unwrap(lua_State*, adl::call_proxy<W,A> const& proxy)
  718. {
  719. object result = const_cast<adl::call_proxy<W,A>&>(proxy);
  720. result.push(result.interpreter());
  721. }
  722. };
  723. template<>
  724. struct value_wrapper_traits<object>
  725. {
  726. typedef boost::mpl::true_ is_specialized;
  727. static lua_State* interpreter(object const& value)
  728. {
  729. return value.interpreter();
  730. }
  731. static void unwrap(lua_State* interpreter, object const& value)
  732. {
  733. value.push(interpreter);
  734. }
  735. static bool check(...)
  736. {
  737. return true;
  738. }
  739. };
  740. template<>
  741. struct value_wrapper_traits<argument>
  742. {
  743. typedef boost::mpl::true_ is_specialized;
  744. static lua_State* interpreter(argument const& value)
  745. {
  746. return value.interpreter();
  747. }
  748. static void unwrap(lua_State* interpreter, argument const& value)
  749. {
  750. value.push(interpreter);
  751. }
  752. static bool check(...)
  753. {
  754. return true;
  755. }
  756. };
  757. template<class Next>
  758. inline void adl::index_proxy<Next>::push(lua_State* interpreter)
  759. {
  760. assert(interpreter == m_interpreter);
  761. value_wrapper_traits<Next>::unwrap(m_interpreter, m_next);
  762. lua_pushvalue(m_interpreter, m_key_index);
  763. lua_gettable(m_interpreter, -2);
  764. lua_remove(m_interpreter, -2);
  765. }
  766. template<class Next>
  767. inline adl::index_proxy<Next>::operator object()
  768. {
  769. detail::stack_pop pop(m_interpreter, 1);
  770. push(m_interpreter);
  771. return object(from_stack(m_interpreter, -1));
  772. }
  773. template<class AccessPolicy>
  774. adl::iterator_proxy<AccessPolicy>::operator object()
  775. {
  776. lua_pushvalue(m_interpreter, m_key_index);
  777. AccessPolicy::get(m_interpreter, m_table_index);
  778. detail::stack_pop pop(m_interpreter, 1);
  779. return object(from_stack(m_interpreter, -1));
  780. }
  781. template<class AccessPolicy>
  782. object detail::basic_iterator<AccessPolicy>::key() const
  783. {
  784. return object(m_key);
  785. }
  786. namespace detail
  787. {
  788. template<
  789. class T
  790. , class ValueWrapper
  791. , class Policies
  792. , class ErrorPolicy
  793. , class ReturnType
  794. >
  795. ReturnType object_cast_aux(
  796. ValueWrapper const& value_wrapper
  797. , T*
  798. , Policies*
  799. , ErrorPolicy*
  800. , ReturnType*
  801. )
  802. {
  803. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  804. value_wrapper
  805. );
  806. #ifndef LUABIND_NO_ERROR_CHECKING
  807. if (!interpreter)
  808. return ErrorPolicy::handle_error(interpreter, typeid(void));
  809. #endif
  810. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value_wrapper);
  811. detail::stack_pop pop(interpreter, 1);
  812. typedef typename detail::find_conversion_policy<
  813. 0
  814. , Policies
  815. >::type converter_generator;
  816. typename mpl::apply_wrap2<converter_generator, T, lua_to_cpp>::type cv;
  817. if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0)
  818. {
  819. return ErrorPolicy::handle_error(interpreter, typeid(T));
  820. }
  821. return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1);
  822. }
  823. # ifdef BOOST_MSVC
  824. # pragma warning(push)
  825. # pragma warning(disable:4702) // unreachable code
  826. # endif
  827. template<class T>
  828. struct throw_error_policy
  829. {
  830. static T handle_error(lua_State* interpreter, type_id const& type_info)
  831. {
  832. #ifndef LUABIND_NO_EXCEPTIONS
  833. throw cast_failed(interpreter, type_info);
  834. #else
  835. cast_failed_callback_fun e = get_cast_failed_callback();
  836. if (e) e(interpreter, type_info);
  837. assert(0 && "object_cast failed. If you want to handle this error use "
  838. "luabind::set_error_callback()");
  839. std::terminate();
  840. #endif
  841. return *(typename boost::remove_reference<T>::type*)0;
  842. }
  843. };
  844. # ifdef BOOST_MSVC
  845. # pragma warning(pop)
  846. # endif
  847. template<class T>
  848. struct nothrow_error_policy
  849. {
  850. static boost::optional<T> handle_error(lua_State*, type_id const&)
  851. {
  852. return boost::optional<T>();
  853. }
  854. };
  855. } // namespace detail
  856. template<class T, class ValueWrapper>
  857. T object_cast(ValueWrapper const& value_wrapper)
  858. {
  859. return detail::object_cast_aux(
  860. value_wrapper
  861. , (T*)0
  862. , (detail::null_type*)0
  863. , (detail::throw_error_policy<T>*)0
  864. , (T*)0
  865. );
  866. }
  867. template<class T, class ValueWrapper, class Policies>
  868. T object_cast(ValueWrapper const& value_wrapper, Policies const&)
  869. {
  870. return detail::object_cast_aux(
  871. value_wrapper
  872. , (T*)0
  873. , (Policies*)0
  874. , (detail::throw_error_policy<T>*)0
  875. , (T*)0
  876. );
  877. }
  878. template<class T, class ValueWrapper>
  879. boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper)
  880. {
  881. return detail::object_cast_aux(
  882. value_wrapper
  883. , (T*)0
  884. , (detail::null_type*)0
  885. , (detail::nothrow_error_policy<T>*)0
  886. , (boost::optional<T>*)0
  887. );
  888. }
  889. template<class T, class ValueWrapper, class Policies>
  890. boost::optional<T> object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&)
  891. {
  892. return detail::object_cast_aux(
  893. value_wrapper
  894. , (T*)0
  895. , (Policies*)0
  896. , (detail::nothrow_error_policy<T>*)0
  897. , (boost::optional<T>*)0
  898. );
  899. }
  900. namespace detail
  901. {
  902. template<int Index>
  903. struct push_args_from_tuple
  904. {
  905. # ifdef LUABIND_CPP0x
  906. template <class Args, class Policies, class N, class E>
  907. static void push_args(
  908. lua_State* L, Args const& args, Policies const& policies, N, E)
  909. {
  910. convert_to_lua_p<N::value + 1>(L, *std::get<N::value>(args), policies);
  911. push_args(
  912. L, args, policies, std::integral_constant<int, N::value + 1>(), E());
  913. }
  914. template <class Args, class Policies, class E>
  915. static void push_args(lua_State* L, Args const&, Policies const&, E, E)
  916. {}
  917. template <class... Args, class Policies = null_type>
  918. static void apply(
  919. lua_State* L, std::tuple<Args...> const& args
  920. , Policies const policies = Policies())
  921. {
  922. push_args(
  923. L
  924. , args
  925. , policies
  926. , std::integral_constant<int, 0>()
  927. , std::integral_constant<int, sizeof...(Args)>()
  928. );
  929. }
  930. # else // LUABIND_CPP0x
  931. template<class H, class T, class Policies>
  932. inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x, const Policies& p)
  933. {
  934. convert_to_lua_p<Index>(L, *x.get_head(), p);
  935. push_args_from_tuple<Index+1>::apply(L, x.get_tail(), p);
  936. }
  937. template<class H, class T>
  938. inline static void apply(lua_State* L, const boost::tuples::cons<H, T>& x)
  939. {
  940. convert_to_lua(L, *x.get_head());
  941. push_args_from_tuple<Index+1>::apply(L, x.get_tail());
  942. }
  943. template<class Policies>
  944. inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {}
  945. inline static void apply(lua_State*, const boost::tuples::null_type&) {}
  946. # endif // LUABIND_CPP0x
  947. };
  948. } // namespace detail
  949. namespace adl
  950. {
  951. template<class ValueWrapper, class Arguments>
  952. struct call_proxy
  953. {
  954. call_proxy(ValueWrapper& value_wrapper, Arguments arguments)
  955. : value_wrapper(&value_wrapper)
  956. , arguments(arguments)
  957. {}
  958. call_proxy(call_proxy const& other)
  959. : value_wrapper(other.value_wrapper)
  960. , arguments(other.arguments)
  961. {
  962. other.value_wrapper = 0;
  963. }
  964. ~call_proxy()
  965. {
  966. if (value_wrapper)
  967. call((detail::null_type*)0);
  968. }
  969. operator object()
  970. {
  971. return call((detail::null_type*)0);
  972. }
  973. template<class Policies>
  974. object operator[](Policies const&)
  975. {
  976. return call((Policies*)0);
  977. }
  978. template<class Policies>
  979. object call(Policies*)
  980. {
  981. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  982. *value_wrapper
  983. );
  984. value_wrapper_traits<ValueWrapper>::unwrap(
  985. interpreter
  986. , *value_wrapper
  987. );
  988. value_wrapper = 0;
  989. detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies());
  990. # ifdef LUABIND_CPP0x
  991. if (detail::pcall(interpreter, std::tuple_size<Arguments>::value, 1))
  992. # else
  993. if (detail::pcall(interpreter, boost::tuples::length<Arguments>::value, 1))
  994. # endif
  995. {
  996. #ifndef LUABIND_NO_EXCEPTIONS
  997. throw luabind::error(interpreter);
  998. #else
  999. error_callback_fun e = get_error_callback();
  1000. if (e) e(interpreter);
  1001. assert(0 && "the lua function threw an error and exceptions are disabled."
  1002. "if you want to handle this error use luabind::set_error_callback()");
  1003. std::terminate();
  1004. #endif
  1005. }
  1006. detail::stack_pop pop(interpreter, 1);
  1007. return object(from_stack(interpreter, -1));
  1008. }
  1009. mutable ValueWrapper* value_wrapper;
  1010. Arguments arguments;
  1011. };
  1012. # ifndef LUABIND_CPP0x
  1013. template<class Derived>
  1014. call_proxy<Derived, boost::tuples::tuple<> >
  1015. object_interface<Derived>::operator()()
  1016. {
  1017. return call_proxy<Derived, boost::tuples::tuple<> >(
  1018. derived()
  1019. , boost::tuples::tuple<>()
  1020. );
  1021. }
  1022. # endif
  1023. // Simple value_wrapper adaptor with the sole purpose of helping with
  1024. // overload resolution. Use this as a function parameter type instead
  1025. // of "object" or "argument" to restrict the parameter to Lua tables.
  1026. template <class Base = object>
  1027. struct table : Base
  1028. {
  1029. table(from_stack const& stack_reference)
  1030. : Base(stack_reference)
  1031. {}
  1032. };
  1033. } // namespace adl
  1034. using adl::table;
  1035. template <class Base>
  1036. struct value_wrapper_traits<adl::table<Base> >
  1037. : value_wrapper_traits<Base>
  1038. {
  1039. static bool check(lua_State* L, int idx)
  1040. {
  1041. return value_wrapper_traits<Base>::check(L, idx) &&
  1042. lua_istable(L, idx);
  1043. }
  1044. };
  1045. inline object newtable(lua_State* interpreter)
  1046. {
  1047. lua_newtable(interpreter);
  1048. detail::stack_pop pop(interpreter, 1);
  1049. return object(from_stack(interpreter, -1));
  1050. }
  1051. // this could be optimized by returning a proxy
  1052. inline object globals(lua_State* interpreter)
  1053. {
  1054. lua_pushvalue(interpreter, LUA_GLOBALSINDEX);
  1055. detail::stack_pop pop(interpreter, 1);
  1056. return object(from_stack(interpreter, -1));
  1057. }
  1058. // this could be optimized by returning a proxy
  1059. inline object registry(lua_State* interpreter)
  1060. {
  1061. lua_pushvalue(interpreter, LUA_REGISTRYINDEX);
  1062. detail::stack_pop pop(interpreter, 1);
  1063. return object(from_stack(interpreter, -1));
  1064. }
  1065. template<class ValueWrapper, class K>
  1066. inline object gettable(ValueWrapper const& table, K const& key)
  1067. {
  1068. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1069. table
  1070. );
  1071. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
  1072. detail::stack_pop pop(interpreter, 2);
  1073. detail::push(interpreter, key);
  1074. lua_gettable(interpreter, -2);
  1075. return object(from_stack(interpreter, -1));
  1076. }
  1077. template<class ValueWrapper, class K, class T>
  1078. inline void settable(ValueWrapper const& table, K const& key, T const& value)
  1079. {
  1080. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1081. table
  1082. );
  1083. // TODO: Exception safe?
  1084. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
  1085. detail::stack_pop pop(interpreter, 1);
  1086. detail::push(interpreter, key);
  1087. detail::push(interpreter, value);
  1088. lua_settable(interpreter, -3);
  1089. }
  1090. template<class ValueWrapper, class K>
  1091. inline object rawget(ValueWrapper const& table, K const& key)
  1092. {
  1093. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1094. table
  1095. );
  1096. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
  1097. detail::stack_pop pop(interpreter, 2);
  1098. detail::push(interpreter, key);
  1099. lua_rawget(interpreter, -2);
  1100. return object(from_stack(interpreter, -1));
  1101. }
  1102. template<class ValueWrapper, class K, class T>
  1103. inline void rawset(ValueWrapper const& table, K const& key, T const& value)
  1104. {
  1105. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1106. table
  1107. );
  1108. // TODO: Exception safe?
  1109. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, table);
  1110. detail::stack_pop pop(interpreter, 1);
  1111. detail::push(interpreter, key);
  1112. detail::push(interpreter, value);
  1113. lua_rawset(interpreter, -3);
  1114. }
  1115. template<class ValueWrapper>
  1116. inline int type(ValueWrapper const& value)
  1117. {
  1118. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1119. value
  1120. );
  1121. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
  1122. detail::stack_pop pop(interpreter, 1);
  1123. return lua_type(interpreter, -1);
  1124. }
  1125. template <class ValueWrapper>
  1126. inline object getmetatable(ValueWrapper const& obj)
  1127. {
  1128. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1129. obj
  1130. );
  1131. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, obj);
  1132. detail::stack_pop pop(interpreter, 2);
  1133. lua_getmetatable(interpreter, -1);
  1134. return object(from_stack(interpreter, -1));
  1135. }
  1136. template <class ValueWrapper1, class ValueWrapper2>
  1137. inline void setmetatable(
  1138. ValueWrapper1 const& obj, ValueWrapper2 const& metatable)
  1139. {
  1140. lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
  1141. obj
  1142. );
  1143. value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, obj);
  1144. detail::stack_pop pop(interpreter, 1);
  1145. value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, metatable);
  1146. lua_setmetatable(interpreter, -2);
  1147. }
  1148. template <class ValueWrapper>
  1149. inline lua_CFunction tocfunction(ValueWrapper const& value)
  1150. {
  1151. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1152. value
  1153. );
  1154. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
  1155. detail::stack_pop pop(interpreter, 1);
  1156. return lua_tocfunction(interpreter, -1);
  1157. }
  1158. template <class T, class ValueWrapper>
  1159. inline T* touserdata(ValueWrapper const& value)
  1160. {
  1161. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1162. value
  1163. );
  1164. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
  1165. detail::stack_pop pop(interpreter, 1);
  1166. return static_cast<T*>(lua_touserdata(interpreter, -1));
  1167. }
  1168. template <class ValueWrapper>
  1169. inline object getupvalue(ValueWrapper const& value, int index)
  1170. {
  1171. lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
  1172. value
  1173. );
  1174. value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
  1175. detail::stack_pop pop(interpreter, 2);
  1176. lua_getupvalue(interpreter, -1, index);
  1177. return object(from_stack(interpreter, -1));
  1178. }
  1179. template <class ValueWrapper1, class ValueWrapper2>
  1180. inline void setupvalue(
  1181. ValueWrapper1 const& function, int index, ValueWrapper2 const& value)
  1182. {
  1183. lua_State* interpreter = value_wrapper_traits<ValueWrapper1>::interpreter(
  1184. function
  1185. );
  1186. value_wrapper_traits<ValueWrapper1>::unwrap(interpreter, function);
  1187. detail::stack_pop pop(interpreter, 1);
  1188. value_wrapper_traits<ValueWrapper2>::unwrap(interpreter, value);
  1189. lua_setupvalue(interpreter, -2, index);
  1190. }
  1191. template <class GetValueWrapper>
  1192. object property(GetValueWrapper const& get)
  1193. {
  1194. lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
  1195. get
  1196. );
  1197. value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
  1198. lua_pushnil(interpreter);
  1199. lua_pushcclosure(interpreter, &detail::property_tag, 2);
  1200. detail::stack_pop pop(interpreter, 1);
  1201. return object(from_stack(interpreter, -1));
  1202. }
  1203. template <class GetValueWrapper, class SetValueWrapper>
  1204. object property(GetValueWrapper const& get, SetValueWrapper const& set)
  1205. {
  1206. lua_State* interpreter = value_wrapper_traits<GetValueWrapper>::interpreter(
  1207. get
  1208. );
  1209. value_wrapper_traits<GetValueWrapper>::unwrap(interpreter, get);
  1210. value_wrapper_traits<SetValueWrapper>::unwrap(interpreter, set);
  1211. lua_pushcclosure(interpreter, &detail::property_tag, 2);
  1212. detail::stack_pop pop(interpreter, 1);
  1213. return object(from_stack(interpreter, -1));
  1214. }
  1215. } // namespace luabind
  1216. #endif // LUABIND_OBJECT_050419_HPP