1 //------------------------------------------------------------------------------
3 https://github.com/vinniefalco/LuaBridge
5 Copyright 2016, Robin Gareus <robin@gareus.org>
6 Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
8 License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 //==============================================================================
30 // We use a structure so we can define everything in the header.
34 //----------------------------------------------------------------------------
36 __index metamethod for a namespace or class static members.
39 Retrieving functions and class static methods, stored in the metatable.
40 Reading global and class static data, stored in the __propget table.
41 Reading global and class properties, stored in the __propget table.
43 static int indexMetaMethod (lua_State* L)
46 lua_getmetatable (L, 1); // push metatable of arg1
49 lua_pushvalue (L, 2); // push key arg2
50 lua_rawget (L, -2); // lookup key in metatable
51 if (lua_isnil (L, -1)) // not found
53 lua_pop (L, 1); // discard nil
54 rawgetfield (L, -1, "__propget"); // lookup __propget in metatable
55 lua_pushvalue (L, 2); // push key arg2
56 lua_rawget (L, -2); // lookup key in __propget
57 lua_remove (L, -2); // discard __propget
58 if (lua_iscfunction (L, -1))
60 lua_remove (L, -2); // discard metatable
61 lua_pushvalue (L, 1); // push arg1
62 lua_call (L, 1, 1); // call cfunction
68 assert (lua_isnil (L, -1));
69 lua_pop (L, 1); // discard nil and fall through
74 assert (lua_istable (L, -1) || lua_iscfunction (L, -1));
80 rawgetfield (L, -1, "__parent");
81 if (lua_istable (L, -1))
83 // Remove metatable and repeat the search in __parent.
88 // Discard metatable and return nil.
89 assert (lua_isnil (L, -1));
99 //----------------------------------------------------------------------------
101 __newindex metamethod for a namespace or class static members.
103 The __propset table stores proxy functions for assignment to:
104 Global and class static data.
105 Global and class properties.
107 static int newindexMetaMethod (lua_State* L)
110 lua_getmetatable (L, 1); // push metatable of arg1
113 rawgetfield (L, -1, "__propset"); // lookup __propset in metatable
114 assert (lua_istable (L, -1));
115 lua_pushvalue (L, 2); // push key arg2
116 lua_rawget (L, -2); // lookup key in __propset
117 lua_remove (L, -2); // discard __propset
118 if (lua_iscfunction (L, -1)) // ensure value is a cfunction
120 lua_remove (L, -2); // discard metatable
121 lua_pushvalue (L, 3); // push new value arg3
122 lua_call (L, 1, 0); // call cfunction
128 assert (lua_isnil (L, -1));
132 rawgetfield (L, -1, "__parent");
133 if (lua_istable (L, -1))
135 // Remove metatable and repeat the search in __parent.
140 assert (lua_isnil (L, -1));
142 result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2));
149 //----------------------------------------------------------------------------
151 lua_CFunction to report an error writing to a read-only value.
153 The name of the variable is in the first upvalue.
155 static int readOnlyError (lua_State* L)
159 s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only";
161 return luaL_error (L, s.c_str ());
164 //----------------------------------------------------------------------------
166 lua_CFunction to get a variable.
168 This is used for global variables or class static data members.
170 The pointer to the data is in the first upvalue.
173 static int getVariable (lua_State* L)
175 assert (lua_islightuserdata (L, lua_upvalueindex (1)));
176 T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1)));
178 Stack <T>::push (L, *ptr);
182 //----------------------------------------------------------------------------
184 lua_CFunction to set a variable.
186 This is used for global variables or class static data members.
188 The pointer to the data is in the first upvalue.
191 static int setVariable (lua_State* L)
193 assert (lua_islightuserdata (L, lua_upvalueindex (1)));
194 T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1)));
196 *ptr = Stack <T>::get (L, 1);
200 //----------------------------------------------------------------------------
202 lua_CFunction to call a function with a return value.
204 This is used for global functions, global properties, class static methods,
205 and class static properties.
207 The function pointer is in the first upvalue.
209 template <class FnPtr,
210 class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
213 typedef typename FuncTraits <FnPtr>::Params Params;
214 static int f (lua_State* L)
216 assert (isfulluserdata (L, lua_upvalueindex (1)));
217 FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
219 ArgList <Params> args (L);
220 Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args));
225 //----------------------------------------------------------------------------
227 lua_CFunction to call a function with no return value.
229 This is used for global functions, global properties, class static methods,
230 and class static properties.
232 The function pointer is in the first upvalue.
234 template <class FnPtr>
235 struct Call <FnPtr, void>
237 typedef typename FuncTraits <FnPtr>::Params Params;
238 static int f (lua_State* L)
240 assert (isfulluserdata (L, lua_upvalueindex (1)));
241 FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
243 ArgList <Params> args (L);
244 FuncTraits <FnPtr>::call (fnptr, args);
249 //----------------------------------------------------------------------------
251 lua_CFunction to call a function with references as arguments.
253 template <class FnPtr,
254 class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
257 typedef typename FuncTraits <FnPtr>::Params Params;
258 static int f (lua_State* L)
260 assert (isfulluserdata (L, lua_upvalueindex (1)));
261 FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
263 ArgList <Params, 1> args (L);
264 Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args));
265 LuaRef v (newTable (L));
266 FuncArgs <Params, 0>::refs (v, args);
272 template <class FnPtr>
273 struct CallRef <FnPtr, void>
275 typedef typename FuncTraits <FnPtr>::Params Params;
276 static int f (lua_State* L)
278 assert (isfulluserdata (L, lua_upvalueindex (1)));
279 FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
281 ArgList <Params, 1> args (L);
282 FuncTraits <FnPtr>::call (fnptr, args);
283 LuaRef v (newTable (L));
284 FuncArgs <Params, 0>::refs (v, args);
291 //----------------------------------------------------------------------------
293 lua_CFunction to call a class member function with a return value.
295 The member function pointer is in the first upvalue.
296 The class userdata object is at the top of the Lua stack.
298 template <class MemFnPtr,
299 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
302 typedef typename FuncTraits <MemFnPtr>::ClassType T;
303 typedef typename FuncTraits <MemFnPtr>::Params Params;
305 static int f (lua_State* L)
307 assert (isfulluserdata (L, lua_upvalueindex (1)));
308 T* const t = Userdata::get <T> (L, 1, false);
309 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
311 ArgList <Params, 2> args (L);
312 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
317 template <class MemFnPtr,
318 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
319 struct CallConstMember
321 typedef typename FuncTraits <MemFnPtr>::ClassType T;
322 typedef typename FuncTraits <MemFnPtr>::Params Params;
324 static int f (lua_State* L)
326 assert (isfulluserdata (L, lua_upvalueindex (1)));
327 T const* const t = Userdata::get <T> (L, 1, true);
328 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
330 ArgList <Params, 2> args(L);
331 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
336 template <class MemFnPtr, class T,
337 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
340 typedef typename FuncTraits <MemFnPtr>::Params Params;
342 static int f (lua_State* L)
344 assert (isfulluserdata (L, lua_upvalueindex (1)));
345 boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
346 T* const tt = t->get();
348 return luaL_error (L, "shared_ptr is nil");
350 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
352 ArgList <Params, 2> args (L);
353 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
358 template <class T, class R>
361 static int f (lua_State* L)
363 boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
364 Stack <boost::shared_ptr<R> >::push (L, boost::dynamic_pointer_cast<R> (t));
370 struct ClassEqualCheck
372 static int f (lua_State* L)
374 T const* const t0 = Userdata::get <T> (L, 1, true);
375 T const* const t1 = Userdata::get <T> (L, 2, true);
376 Stack <bool>::push (L, t0 == t1);
382 template <class T, class R>
385 static int f (lua_State* L)
387 T * const t = Userdata::get <T> (L, 1, false );
388 Stack <R*>::push (L, dynamic_cast<R*>(t));
393 template <class T, class R>
394 struct CastConstClass
396 static int f (lua_State* L)
398 T const* const t = Userdata::get <T> (L, 1, true);
399 Stack <R const*>::push (L, dynamic_cast<R const*>(t));
408 static int f (lua_State* L)
410 boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
411 Stack <bool>::push (L, t == 0);
419 static int f (lua_State* L)
422 boost::weak_ptr<T> tw = luabridge::Stack<boost::weak_ptr<T> >::get (L, 1);
423 boost::shared_ptr<T> const t = tw.lock();
425 T* const tt = t.get();
428 Stack <bool>::push (L, rv);
433 template <class MemFnPtr, class T,
434 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
435 struct CallMemberWPtr
437 typedef typename FuncTraits <MemFnPtr>::Params Params;
439 static int f (lua_State* L)
441 assert (isfulluserdata (L, lua_upvalueindex (1)));
442 boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
443 boost::shared_ptr<T> const t = tw->lock();
445 return luaL_error (L, "cannot lock weak_ptr");
447 T* const tt = t.get();
449 return luaL_error (L, "weak_ptr is nil");
451 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
453 ArgList <Params, 2> args (L);
454 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
460 lua_CFunction to calls for function references.
462 template <class MemFnPtr,
463 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
466 typedef typename FuncTraits <MemFnPtr>::ClassType T;
467 typedef typename FuncTraits <MemFnPtr>::Params Params;
469 static int f (lua_State* L)
471 assert (isfulluserdata (L, lua_upvalueindex (1)));
472 T* const t = Userdata::get <T> (L, 1, false);
473 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
475 ArgList <Params, 2> args (L);
476 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
477 LuaRef v (newTable (L));
478 FuncArgs <Params, 0>::refs (v, args);
484 template <class MemFnPtr,
485 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
486 struct CallConstMemberRef
488 typedef typename FuncTraits <MemFnPtr>::ClassType T;
489 typedef typename FuncTraits <MemFnPtr>::Params Params;
491 static int f (lua_State* L)
493 assert (isfulluserdata (L, lua_upvalueindex (1)));
494 T const* const t = Userdata::get <T> (L, 1, true);
495 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
497 ArgList <Params, 2> args(L);
498 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
499 LuaRef v (newTable (L));
500 FuncArgs <Params, 0>::refs (v, args);
506 template <class MemFnPtr, class T,
507 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
508 struct CallMemberRefPtr
510 typedef typename FuncTraits <MemFnPtr>::Params Params;
512 static int f (lua_State* L)
514 assert (isfulluserdata (L, lua_upvalueindex (1)));
515 boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
516 T* const tt = t->get();
518 return luaL_error (L, "shared_ptr is nil");
520 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
522 ArgList <Params, 2> args (L);
523 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
524 LuaRef v (newTable (L));
525 FuncArgs <Params, 0>::refs (v, args);
531 template <class MemFnPtr, class T,
532 class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
533 struct CallMemberRefWPtr
535 typedef typename FuncTraits <MemFnPtr>::Params Params;
537 static int f (lua_State* L)
539 assert (isfulluserdata (L, lua_upvalueindex (1)));
540 boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
541 boost::shared_ptr<T> const t = tw->lock();
543 return luaL_error (L, "cannot lock weak_ptr");
545 T* const tt = t.get();
547 return luaL_error (L, "weak_ptr is nil");
549 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
551 ArgList <Params, 2> args (L);
552 Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
553 LuaRef v (newTable (L));
554 FuncArgs <Params, 0>::refs (v, args);
560 //----------------------------------------------------------------------------
562 lua_CFunction to call a class member function with no return value.
564 The member function pointer is in the first upvalue.
565 The class userdata object is at the top of the Lua stack.
567 template <class MemFnPtr>
568 struct CallMember <MemFnPtr, void>
570 typedef typename FuncTraits <MemFnPtr>::ClassType T;
571 typedef typename FuncTraits <MemFnPtr>::Params Params;
573 static int f (lua_State* L)
575 assert (isfulluserdata (L, lua_upvalueindex (1)));
576 T* const t = Userdata::get <T> (L, 1, false);
577 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
579 ArgList <Params, 2> args (L);
580 FuncTraits <MemFnPtr>::call (t, fnptr, args);
585 template <class MemFnPtr>
586 struct CallConstMember <MemFnPtr, void>
588 typedef typename FuncTraits <MemFnPtr>::ClassType T;
589 typedef typename FuncTraits <MemFnPtr>::Params Params;
591 static int f (lua_State* L)
593 assert (isfulluserdata (L, lua_upvalueindex (1)));
594 T const* const t = Userdata::get <T> (L, 1, true);
595 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
597 ArgList <Params, 2> args (L);
598 FuncTraits <MemFnPtr>::call (t, fnptr, args);
603 template <class MemFnPtr, class T>
604 struct CallMemberPtr <MemFnPtr, T, void>
606 typedef typename FuncTraits <MemFnPtr>::Params Params;
608 static int f (lua_State* L)
610 assert (isfulluserdata (L, lua_upvalueindex (1)));
611 boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
612 T* const tt = t->get();
613 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
615 ArgList <Params, 2> args (L);
616 FuncTraits <MemFnPtr>::call (tt, fnptr, args);
621 template <class MemFnPtr, class T>
622 struct CallMemberWPtr <MemFnPtr, T, void>
624 typedef typename FuncTraits <MemFnPtr>::Params Params;
626 static int f (lua_State* L)
628 assert (isfulluserdata (L, lua_upvalueindex (1)));
629 boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
630 boost::shared_ptr<T> const t = tw->lock();
632 return luaL_error (L, "cannot lock weak_ptr");
634 T* const tt = t.get();
636 return luaL_error (L, "weak_ptr is nil");
638 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
640 ArgList <Params, 2> args (L);
641 FuncTraits <MemFnPtr>::call (tt, fnptr, args);
646 template <class MemFnPtr>
647 struct CallMemberRef <MemFnPtr, void>
649 typedef typename FuncTraits <MemFnPtr>::ClassType T;
650 typedef typename FuncTraits <MemFnPtr>::Params Params;
652 static int f (lua_State* L)
654 assert (isfulluserdata (L, lua_upvalueindex (1)));
655 T* const t = Userdata::get <T> (L, 1, false);
656 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
658 ArgList <Params, 2> args (L);
659 FuncTraits <MemFnPtr>::call (t, fnptr, args);
660 LuaRef v (newTable (L));
661 FuncArgs <Params, 0>::refs (v, args);
667 template <class MemFnPtr>
668 struct CallConstMemberRef <MemFnPtr, void>
670 typedef typename FuncTraits <MemFnPtr>::ClassType T;
671 typedef typename FuncTraits <MemFnPtr>::Params Params;
673 static int f (lua_State* L)
675 assert (isfulluserdata (L, lua_upvalueindex (1)));
676 T const* const t = Userdata::get <T> (L, 1, true);
677 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
679 ArgList <Params, 2> args (L);
680 FuncTraits <MemFnPtr>::call (t, fnptr, args);
681 LuaRef v (newTable (L));
682 FuncArgs <Params, 0>::refs (v, args);
688 template <class MemFnPtr, class T>
689 struct CallMemberRefPtr <MemFnPtr, T, void>
691 typedef typename FuncTraits <MemFnPtr>::Params Params;
693 static int f (lua_State* L)
695 assert (isfulluserdata (L, lua_upvalueindex (1)));
696 boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
697 T* const tt = t->get();
699 return luaL_error (L, "shared_ptr is nil");
701 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
703 ArgList <Params, 2> args (L);
704 FuncTraits <MemFnPtr>::call (tt, fnptr, args);
705 LuaRef v (newTable (L));
706 FuncArgs <Params, 0>::refs (v, args);
712 template <class MemFnPtr, class T>
713 struct CallMemberRefWPtr <MemFnPtr, T, void>
715 typedef typename FuncTraits <MemFnPtr>::Params Params;
717 static int f (lua_State* L)
719 assert (isfulluserdata (L, lua_upvalueindex (1)));
720 boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
721 boost::shared_ptr<T> const t = tw->lock();
723 return luaL_error (L, "cannot lock weak_ptr");
725 T* const tt = t.get();
727 return luaL_error (L, "weak_ptr is nil");
729 MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
731 ArgList <Params, 2> args (L);
732 FuncTraits <MemFnPtr>::call (tt, fnptr, args);
733 LuaRef v (newTable (L));
734 FuncArgs <Params, 0>::refs (v, args);
740 //--------------------------------------------------------------------------
742 lua_CFunction to call a class member lua_CFunction.
744 The member function pointer is in the first upvalue.
745 The class userdata object is at the top of the Lua stack.
748 struct CallMemberCFunction
750 static int f (lua_State* L)
752 assert (isfulluserdata (L, lua_upvalueindex (1)));
753 typedef int (T::*MFP)(lua_State* L);
754 T* const t = Userdata::get <T> (L, 1, false);
755 MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
757 return (t->*fnptr) (L);
762 struct CallConstMemberCFunction
764 static int f (lua_State* L)
766 assert (isfulluserdata (L, lua_upvalueindex (1)));
767 typedef int (T::*MFP)(lua_State* L);
768 T const* const t = Userdata::get <T> (L, 1, true);
769 MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
771 return (t->*fnptr) (L);
775 //--------------------------------------------------------------------------
779 template <class MemFnPtr, bool isConst>
780 struct CallMemberFunctionHelper
782 static void add (lua_State* L, char const* name, MemFnPtr mf)
784 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
785 lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1);
786 lua_pushvalue (L, -1);
787 rawsetfield (L, -5, name); // const table
788 rawsetfield (L, -3, name); // class table
792 template <class MemFnPtr>
793 struct CallMemberFunctionHelper <MemFnPtr, false>
795 static void add (lua_State* L, char const* name, MemFnPtr mf)
797 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
798 lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1);
799 rawsetfield (L, -3, name); // class table
803 template <class MemFnPtr>
804 struct CallMemberPtrFunctionHelper
806 typedef typename FuncTraits <MemFnPtr>::ClassType T;
807 static void add (lua_State* L, char const* name, MemFnPtr mf)
809 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
810 lua_pushcclosure (L, &CallMemberPtr <MemFnPtr, T>::f, 1);
811 rawsetfield (L, -3, name); // class table
815 template <class MemFnPtr>
816 struct CallMemberRefPtrFunctionHelper
818 typedef typename FuncTraits <MemFnPtr>::ClassType T;
819 static void add (lua_State* L, char const* name, MemFnPtr mf)
821 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
822 lua_pushcclosure (L, &CallMemberRefPtr <MemFnPtr, T>::f, 1);
823 rawsetfield (L, -3, name); // class table
827 template <class MemFnPtr>
828 struct CallMemberWPtrFunctionHelper
830 typedef typename FuncTraits <MemFnPtr>::ClassType T;
831 static void add (lua_State* L, char const* name, MemFnPtr mf)
833 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
834 lua_pushcclosure (L, &CallMemberWPtr <MemFnPtr, T>::f, 1);
835 rawsetfield (L, -3, name); // class table
839 template <class MemFnPtr>
840 struct CallMemberRefWPtrFunctionHelper
842 typedef typename FuncTraits <MemFnPtr>::ClassType T;
843 static void add (lua_State* L, char const* name, MemFnPtr mf)
845 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
846 lua_pushcclosure (L, &CallMemberRefWPtr <MemFnPtr, T>::f, 1);
847 rawsetfield (L, -3, name); // class table
851 template <class MemFnPtr, bool isConst>
852 struct CallMemberRefFunctionHelper
854 static void add (lua_State* L, char const* name, MemFnPtr mf)
856 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
857 lua_pushcclosure (L, &CallConstMemberRef <MemFnPtr>::f, 1);
858 lua_pushvalue (L, -1);
859 rawsetfield (L, -5, name); // const table
860 rawsetfield (L, -3, name); // class table
864 template <class MemFnPtr>
865 struct CallMemberRefFunctionHelper <MemFnPtr, false>
867 static void add (lua_State* L, char const* name, MemFnPtr mf)
869 new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
870 lua_pushcclosure (L, &CallMemberRef <MemFnPtr>::f, 1);
871 rawsetfield (L, -3, name); // class table
875 //--------------------------------------------------------------------------
877 __gc metamethod for a class.
880 static int gcMetaMethod (lua_State* L)
882 Userdata* const ud = Userdata::getExact <C> (L, 1);
887 static int gcNOOPMethod (lua_State* L)
892 //--------------------------------------------------------------------------
894 lua_CFunction to get a class data member.
896 The pointer-to-member is in the first upvalue.
897 The class userdata object is at the top of the Lua stack.
899 template <class C, typename T>
900 static int getProperty (lua_State* L)
902 C const* const c = Userdata::get <C> (L, 1, true);
903 T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
904 Stack <T>::push (L, c->**mp);
908 //--------------------------------------------------------------------------
911 lua_CFunction to get a constant (enum)
913 template <typename U>
914 static int getConst (lua_State* L)
916 U *v = static_cast <U *> (lua_touserdata (L, lua_upvalueindex (1)));
918 Stack <U>::push (L, *v);
922 //--------------------------------------------------------------------------
924 lua_CFunction to set a class data member.
926 The pointer-to-member is in the first upvalue.
927 The class userdata object is at the top of the Lua stack.
929 template <class C, typename T>
930 static int setProperty (lua_State* L)
932 C* const c = Userdata::get <C> (L, 1, false);
933 T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
934 c->**mp = Stack <T>::get (L, 2);
938 //--------------------------------------------------------------------------
940 // metatable callback for "array[index]"
941 template <typename T>
942 static int array_index (lua_State* L) {
943 T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
944 int const index = luabridge::Stack<int>::get (L, 2);
945 luabridge::Stack<T>::push (L, (*parray)[index-1]);
949 // metatable callback for "array[index] = value"
950 template <typename T>
951 static int array_newindex (lua_State* L) {
952 T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
953 int const index = luabridge::Stack<int>::get (L, 2);
954 T const value = luabridge::Stack<T>::get (L, 3);
955 (*parray)[index-1] = value;
959 template <typename T>
960 static int getArray (lua_State* L) {
961 T *v = luabridge::Stack<T*>::get (L, 1);
962 T** parray = (T**) lua_newuserdata(L, sizeof(T**));
964 luaL_getmetatable(L, typeid(T).name());
965 lua_setmetatable(L, -2);
969 // copy complete c array to lua table
970 template <typename T>
971 static int getTable (lua_State* L) {
972 T *v = luabridge::Stack<T*>::get (L, 1);
973 const int cnt = luabridge::Stack<int>::get (L, 2);
976 for (int i = 0; i < cnt; ++i) {
983 // copy lua table to c array
984 template <typename T>
985 static int setTable (lua_State* L) {
986 T *v = luabridge::Stack<T*>::get (L, 1);
987 LuaRef t (LuaRef::fromStack(L, 2));
988 const int cnt = luabridge::Stack<int>::get (L, 3);
989 for (int i = 0; i < cnt; ++i) {
995 // return same array at an offset
996 template <typename T>
997 static int offsetArray (lua_State* L) {
998 T *v = luabridge::Stack<T*>::get (L, 1);
999 const unsigned int i = luabridge::Stack<unsigned int>::get (L, 2);
1000 Stack <T*>::push (L, &v[i]);
1004 //--------------------------------------------------------------------------
1009 // read lua table into C++ std::list
1010 template <class T, class C>
1011 static int tableToListHelper (lua_State *L, C * const t)
1013 if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1014 if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1015 lua_pushvalue (L, -1);
1017 while (lua_next (L, -2)) {
1018 lua_pushvalue (L, -2);
1019 T const value = Stack<T>::get (L, -2);
1020 t->push_back (value);
1025 Stack<C>::push (L, *t);
1029 template <class T, class C>
1030 static int tableToList (lua_State *L)
1032 C * const t = Userdata::get<C> (L, 1, false);
1033 return tableToListHelper<T, C> (L, t);
1036 template <class T, class C>
1037 static int ptrTableToList (lua_State *L)
1039 boost::shared_ptr<C> const* const t = Userdata::get<boost::shared_ptr<C> > (L, 1, true);
1040 if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1041 return tableToListHelper<T, C> (L, t->get());
1044 //--------------------------------------------------------------------------
1045 template <class T, class C>
1046 static int listIterIter (lua_State *L) {
1047 typedef typename C::const_iterator IterType;
1048 IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1049 IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1052 if ((*iter) == (*end)) {
1055 Stack <T>::push (L, **iter);
1060 // generate an iterator
1061 template <class T, class C>
1062 static int listIterHelper (lua_State *L, C * const t)
1064 if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1065 typedef typename C::const_iterator IterType;
1066 new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1067 new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1068 lua_pushcclosure (L, listIterIter<T, C>, 2);
1072 template <class T, class C>
1073 static int listIter (lua_State *L)
1075 C * const t = Userdata::get <C> (L, 1, false);
1076 return listIterHelper<T, C> (L, t);
1079 template <class T, class C>
1080 static int ptrListIter (lua_State *L)
1082 boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> >(L, 1, true);
1083 if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1084 return listIterHelper<T, C> (L, t->get());
1087 //--------------------------------------------------------------------------
1088 // generate table from std::list
1089 template <class T, class C>
1090 static int listToTableHelper (lua_State *L, C const* const t)
1092 if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1093 #if 0 // direct lua api
1094 lua_createtable(L, t->size(), 0);
1095 int newTable = lua_gettop(L);
1097 for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1098 Stack<T>::push(L, (*iter));
1099 lua_rawseti (L, newTable, index);
1101 #else // luabridge way
1105 for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1113 template <class T, class C>
1114 static int listToTable (lua_State *L)
1116 C const* const t = Userdata::get <C> (L, 1, true);
1117 return listToTableHelper<T, C> (L, t);
1120 template <class T, class C>
1121 static int ptrListToTable (lua_State *L)
1123 boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> > (L, 1, true);
1124 if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1125 return listToTableHelper<T, C> (L, t->get());
1128 //--------------------------------------------------------------------------
1129 // generate std::map from table
1131 template <class K, class V>
1132 static int tableToMap (lua_State *L)
1134 typedef std::map<K, V> C;
1135 C * const t = Userdata::get <C> (L, 1, true);
1136 if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1137 if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1139 lua_pushvalue (L, -1);
1141 while (lua_next (L, -2)) {
1142 lua_pushvalue (L, -2);
1143 K const key = Stack<K>::get (L, -1);
1144 V const value = Stack<V>::get (L, -2);
1145 t->insert (std::pair<K,V> (key, value));
1146 //(*t)[key] = value;
1151 Stack<C>::push (L, *t);
1155 // iterate over a std::map
1156 template <class K, class V>
1157 static int mapIterIter (lua_State *L)
1159 typedef std::map<K, V> C;
1160 typedef typename C::const_iterator IterType;
1161 IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1162 IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1165 if ((*iter) == (*end)) {
1168 Stack <K>::push (L, (*iter)->first);
1169 Stack <V>::push (L, (*iter)->second);
1174 // generate iterator
1175 template <class K, class V>
1176 static int mapIter (lua_State *L)
1178 typedef std::map<K, V> C;
1179 C * const t = Userdata::get <C> (L, 1, false);
1180 if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1181 typedef typename C::const_iterator IterType;
1182 new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1183 new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1184 lua_pushcclosure (L, mapIterIter<K, V>, 2);
1188 // generate table from std::map
1189 template <class K, class V>
1190 static int mapToTable (lua_State *L)
1192 typedef std::map<K, V> C;
1193 C const* const t = Userdata::get <C> (L, 1, true);
1194 if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1198 for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1199 v[(*iter).first] = (*iter).second;
1205 //--------------------------------------------------------------------------
1206 // generate std::set from table keys ( table[member] = true )
1207 // http://www.lua.org/pil/11.5.html
1210 static int tableToSet (lua_State *L)
1212 typedef std::set<T> C;
1213 C * const t = Userdata::get <C> (L, 1, true);
1214 if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1215 if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1217 lua_pushvalue (L, -1);
1219 while (lua_next (L, -2)) {
1220 lua_pushvalue (L, -2);
1221 T const member = Stack<T>::get (L, -1);
1222 bool const v = Stack<bool>::get (L, -2);
1230 Stack<C>::push (L, *t);
1234 // iterate over a std::set, explicit "true" value.
1235 // compare to http://www.lua.org/pil/11.5.html
1237 static int setIterIter (lua_State *L)
1239 typedef std::set<T> C;
1240 typedef typename C::const_iterator IterType;
1241 IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1242 IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1245 if ((*iter) == (*end)) {
1248 Stack <T>::push (L, **iter);
1249 Stack <bool>::push (L, true);
1254 // generate iterator
1256 static int setIter (lua_State *L)
1258 typedef std::set<T> C;
1259 C * const t = Userdata::get <C> (L, 1, false);
1260 if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1261 typedef typename C::const_iterator IterType;
1262 new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1263 new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1264 lua_pushcclosure (L, setIterIter<T>, 2);
1268 // generate table from std::set
1270 static int setToTable (lua_State *L)
1272 typedef std::set<T> C;
1273 C const* const t = Userdata::get <C> (L, 1, true);
1274 if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1278 for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1285 //--------------------------------------------------------------------------
1286 // bitset { num = true }
1287 // compare to http://www.lua.org/pil/11.5.html
1288 template <unsigned int T>
1289 static int tableToBitSet (lua_State *L)
1291 typedef std::bitset<T> C;
1292 C * const t = Userdata::get <C> (L, 1, true);
1293 if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1294 if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1296 lua_pushvalue (L, -1);
1298 while (lua_next (L, -2)) {
1299 lua_pushvalue (L, -2);
1300 unsigned int const member = Stack<unsigned int>::get (L, -1);
1301 bool const v = Stack<bool>::get (L, -2);
1302 if (member < T && v) {
1309 Stack<C>::push (L, *t);
1313 // generate table from std::bitset
1314 template <unsigned int T>
1315 static int bitSetToTable (lua_State *L)
1317 typedef std::bitset<T> C;
1318 C const* const t = Userdata::get <C> (L, 1, true);
1319 if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1323 for (unsigned int i = 0; i < T; ++i) {
1334 /* vim: set et sw=2: */