Ardour  9.0-pre0-2168-g0459902b9a
CFunctions.h
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 /*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2016, Robin Gareus <robin@gareus.org>
6  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
7 
8  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
9 
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:
16 
17  The above copyright notice and this permission notice shall be included in all
18  copies or substantial portions of the Software.
19 
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
26  SOFTWARE.
27 */
28 //==============================================================================
29 
30 // We use a structure so we can define everything in the header.
31 //
32 struct CFunc
33 {
34  //----------------------------------------------------------------------------
43  static int indexMetaMethod (lua_State* L)
44  {
45  int result = 0;
46  lua_getmetatable (L, 1); // push metatable of arg1
47  for (;;)
48  {
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
52  {
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))
59  {
60  lua_remove (L, -2); // discard metatable
61  lua_pushvalue (L, 1); // push arg1
62  lua_call (L, 1, 1); // call cfunction
63  result = 1;
64  break;
65  }
66  else
67  {
68  assert (lua_isnil (L, -1));
69  lua_pop (L, 1); // discard nil and fall through
70  }
71  }
72  else
73  {
74  assert (lua_istable (L, -1) || lua_iscfunction (L, -1));
75  lua_remove (L, -2);
76  result = 1;
77  break;
78  }
79 
80  rawgetfield (L, -1, "__parent");
81  if (lua_istable (L, -1))
82  {
83  // Remove metatable and repeat the search in __parent.
84  lua_remove (L, -2);
85  }
86  else
87  {
88  // Discard metatable and return nil.
89  assert (lua_isnil (L, -1));
90  lua_remove (L, -2);
91  result = 1;
92  break;
93  }
94  }
95 
96  return result;
97  }
98 
99  //----------------------------------------------------------------------------
108  {
109  int result = 0;
110  lua_getmetatable (L, 1); // push metatable of arg1
111  for (;;)
112  {
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
119  {
120  lua_remove (L, -2); // discard metatable
121  lua_pushvalue (L, 3); // push new value arg3
122  lua_call (L, 1, 0); // call cfunction
123  result = 0;
124  break;
125  }
126  else
127  {
128  assert (lua_isnil (L, -1));
129  lua_pop (L, 1);
130  }
131 
132  rawgetfield (L, -1, "__parent");
133  if (lua_istable (L, -1))
134  {
135  // Remove metatable and repeat the search in __parent.
136  lua_remove (L, -2);
137  }
138  else
139  {
140  assert (lua_isnil (L, -1));
141  lua_pop (L, 2);
142  result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2));
143  }
144  }
145 
146  return result;
147  }
148 
149  //----------------------------------------------------------------------------
155  static int readOnlyError (lua_State* L)
156  {
157  std::string s;
158 
159  s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only";
160 
161  return luaL_error (L, s.c_str ());
162  }
163 
164  //----------------------------------------------------------------------------
172  template <class T>
173  static int getVariable (lua_State* L)
174  {
175  assert (lua_islightuserdata (L, lua_upvalueindex (1)));
176  T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1)));
177  assert (ptr != 0);
178  Stack <T>::push (L, *ptr);
179  return 1;
180  }
181 
182  //----------------------------------------------------------------------------
190  template <class T>
191  static int setVariable (lua_State* L)
192  {
193  assert (lua_islightuserdata (L, lua_upvalueindex (1)));
194  T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1)));
195  assert (ptr != 0);
196  *ptr = Stack <T>::get (L, 1);
197  return 0;
198  }
199 
200  //----------------------------------------------------------------------------
209  template <class FnPtr,
210  class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
211  struct Call
212  {
214  static int f (lua_State* L)
215  {
216  assert (isfulluserdata (L, lua_upvalueindex (1)));
217  FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
218  assert (fnptr != 0);
219  ArgList <Params> args (L);
221  return 1;
222  }
223  };
224 
225  //----------------------------------------------------------------------------
234  template <class FnPtr>
235  struct Call <FnPtr, void>
236  {
238  static int f (lua_State* L)
239  {
240  assert (isfulluserdata (L, lua_upvalueindex (1)));
241  FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
242  assert (fnptr != 0);
243  ArgList <Params> args (L);
244  FuncTraits <FnPtr>::call (fnptr, args);
245  return 0;
246  }
247  };
248 
249  //----------------------------------------------------------------------------
253  template <class FnPtr,
254  class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
255  struct CallRef
256  {
258  static int f (lua_State* L)
259  {
260  assert (isfulluserdata (L, lua_upvalueindex (1)));
261  FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
262  assert (fnptr != 0);
263  ArgList <Params, 1> args (L);
265  LuaRef v (newTable (L));
266  FuncArgs <Params, 0>::refs (v, args);
267  v.push(L);
268  return 2;
269  }
270  };
271 
272  template <class FnPtr>
273  struct CallRef <FnPtr, void>
274  {
276  static int f (lua_State* L)
277  {
278  assert (isfulluserdata (L, lua_upvalueindex (1)));
279  FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
280  assert (fnptr != 0);
281  ArgList <Params, 1> args (L);
282  FuncTraits <FnPtr>::call (fnptr, args);
283  LuaRef v (newTable (L));
284  FuncArgs <Params, 0>::refs (v, args);
285  v.push(L);
286  return 1;
287  }
288  };
289 
290 
291  //----------------------------------------------------------------------------
298  template <class MemFnPtr,
299  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
300  struct CallMember
301  {
304 
305  static int f (lua_State* L)
306  {
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)));
310  assert (fnptr != 0);
311  ArgList <Params, 2> args (L);
313  return 1;
314  }
315  };
316 
317  template <class MemFnPtr,
318  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
320  {
323 
324  static int f (lua_State* L)
325  {
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)));
329  assert (fnptr != 0);
330  ArgList <Params, 2> args(L);
332  return 1;
333  }
334  };
335 
336  template <class MemFnPtr, class T,
337  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
339  {
341 
342  static int f (lua_State* L)
343  {
344  assert (isfulluserdata (L, lua_upvalueindex (1)));
345  std::shared_ptr<T>* const t = Userdata::get <std::shared_ptr<T> > (L, 1, false);
346  T* const tt = t->get();
347  if (!tt) {
348  return luaL_error (L, "shared_ptr is nil");
349  }
350  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
351  assert (fnptr != 0);
352  ArgList <Params, 2> args (L);
354  return 1;
355  }
356  };
357 
358  template <class MemFnPtr, class T,
359  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
361  {
363 
364  static int f (lua_State* L)
365  {
366  assert (isfulluserdata (L, lua_upvalueindex (1)));
367  std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
368  T* const tt = const_cast<T*> (t->get());
369  if (!tt) {
370  return luaL_error (L, "shared_ptr is nil");
371  }
372  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
373  assert (fnptr != 0);
374  ArgList <Params, 2> args (L);
376  return 1;
377  }
378  };
379 
380  template <class T, class R>
382  {
383  static int f (lua_State* L)
384  {
385  std::shared_ptr<T> t = luabridge::Stack<std::shared_ptr<T> >::get (L, 1);
386  Stack <std::shared_ptr<R> >::push (L, std::dynamic_pointer_cast<R> (t));
387  return 1;
388  }
389  };
390 
391  template <class T>
393  {
394  static int f (lua_State* L)
395  {
396  T const* const t0 = Userdata::get <T> (L, 1, true);
397  T const* const t1 = Userdata::get <T> (L, 2, true);
398  Stack <bool>::push (L, t0 == t1);
399  return 1;
400  }
401  };
402 
403  template <class T, class R>
404  struct CastClass
405  {
406  static int f (lua_State* L)
407  {
408  T * const t = Userdata::get <T> (L, 1, false );
409  Stack <R*>::push (L, dynamic_cast<R*>(t));
410  return 1;
411  }
412  };
413 
414  template <class T, class R>
416  {
417  static int f (lua_State* L)
418  {
419  T const* const t = Userdata::get <T> (L, 1, true);
420  Stack <R const*>::push (L, dynamic_cast<R const*>(t));
421  return 1;
422  }
423  };
424 
425  template <class T>
427  {
428  static int f (lua_State* L)
429  {
430  std::shared_ptr<T> t = luabridge::Stack<std::shared_ptr<T> >::get (L, 1);
431  Stack <bool>::push (L, t == 0);
432  return 1;
433  }
434  };
435 
436  template <class T>
438  {
439  static int f (lua_State* L)
440  {
441  bool rv = true;
442  std::weak_ptr<T> tw = luabridge::Stack<std::weak_ptr<T> >::get (L, 1);
443  std::shared_ptr<T> const t = tw.lock();
444  if (t) {
445  T* const tt = t.get();
446  rv = (tt == 0);
447  }
448  Stack <bool>::push (L, rv);
449  return 1;
450  }
451  };
452 
453  template <class T>
455  {
456  static int f (lua_State* L)
457  {
458  std::shared_ptr<T> t0 = luabridge::Stack<std::shared_ptr<T> >::get (L, 1);
459  std::shared_ptr<T> t1 = luabridge::Stack<std::shared_ptr<T> >::get (L, 2);
460  Stack <bool>::push (L, t0 == t1);
461  return 1;
462  }
463  };
464 
465  template <class T>
467  {
468  static int f (lua_State* L)
469  {
470  bool rv = false;
471  std::weak_ptr<T> tw0 = luabridge::Stack<std::weak_ptr<T> >::get (L, 1);
472  std::weak_ptr<T> tw1 = luabridge::Stack<std::weak_ptr<T> >::get (L, 2);
473  std::shared_ptr<T> const t0 = tw0.lock();
474  std::shared_ptr<T> const t1 = tw1.lock();
475  if (t0 && t1) {
476  T* const tt0 = t0.get();
477  T* const tt1 = t1.get();
478  rv = (tt0 == tt1);
479  }
480  Stack <bool>::push (L, rv);
481  return 1;
482  }
483  };
484 
485  template <class T>
486  struct ClassEqualCheck<std::shared_ptr<T> >
487  {
488  static int f (lua_State* L)
489  {
490  return PtrEqualCheck<T>::f (L);
491  }
492  };
493 
494  template <class T>
495  struct ClassEqualCheck<std::weak_ptr<T> >
496  {
497  static int f (lua_State* L)
498  {
499  return WPtrEqualCheck<T>::f (L);
500  }
501  };
502 
503  template <class C, typename T>
504  static int getPtrProperty (lua_State* L)
505  {
506  std::shared_ptr<C> cp = luabridge::Stack<std::shared_ptr<C> >::get (L, 1);
507  C const* const c = cp.get();
508  if (!c) {
509  return luaL_error (L, "shared_ptr is nil");
510  }
511  T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
512  Stack <T>::push (L, c->**mp);
513  return 1;
514  }
515 
516  template <class C, typename T>
517  static int getWPtrProperty (lua_State* L)
518  {
519  std::weak_ptr<C> cw = luabridge::Stack<std::weak_ptr<C> >::get (L, 1);
520  std::shared_ptr<C> const cp = cw.lock();
521  if (!cp) {
522  return luaL_error (L, "cannot lock weak_ptr");
523  }
524  C const* const c = cp.get();
525  if (!c) {
526  return luaL_error (L, "weak_ptr is nil");
527  }
528  T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
529  Stack <T>::push (L, c->**mp);
530  return 1;
531  }
532 
533  template <class C, typename T>
534  static int setPtrProperty (lua_State* L)
535  {
536  std::shared_ptr<C> cp = luabridge::Stack<std::shared_ptr<C> >::get (L, 1);
537  C* const c = cp.get();
538  if (!c) {
539  return luaL_error (L, "shared_ptr is nil");
540  }
541  T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
542  c->**mp = Stack <T>::get (L, 2);
543  return 0;
544  }
545 
546  template <class C, typename T>
547  static int setWPtrProperty (lua_State* L)
548  {
549  std::weak_ptr<C> cw = luabridge::Stack<std::weak_ptr<C> >::get (L, 1);
550  std::shared_ptr<C> cp = cw.lock();
551  if (!cp) {
552  return luaL_error (L, "cannot lock weak_ptr");
553  }
554  C* const c = cp.get();
555  if (!c) {
556  return luaL_error (L, "weak_ptr is nil");
557  }
558  T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
559  c->**mp = Stack <T>::get (L, 2);
560  return 0;
561  }
562 
563  template <class MemFnPtr, class T,
564  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
566  {
568 
569  static int f (lua_State* L)
570  {
571  assert (isfulluserdata (L, lua_upvalueindex (1)));
572  std::weak_ptr<T>* const tw = Userdata::get <std::weak_ptr<T> > (L, 1, false);
573  std::shared_ptr<T> const t = tw->lock();
574  if (!t) {
575  return luaL_error (L, "cannot lock weak_ptr");
576  }
577  T* const tt = t.get();
578  if (!tt) {
579  return luaL_error (L, "weak_ptr is nil");
580  }
581  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
582  assert (fnptr != 0);
583  ArgList <Params, 2> args (L);
585  return 1;
586  }
587  };
588 
592  template <class MemFnPtr,
593  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
595  {
598 
599  static int f (lua_State* L)
600  {
601  assert (isfulluserdata (L, lua_upvalueindex (1)));
602  T* const t = Userdata::get <T> (L, 1, false);
603  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
604  assert (fnptr != 0);
605  ArgList <Params, 2> args (L);
607  LuaRef v (newTable (L));
608  FuncArgs <Params, 0>::refs (v, args);
609  v.push(L);
610  return 2;
611  }
612  };
613 
614  template <class MemFnPtr,
615  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
617  {
620 
621  static int f (lua_State* L)
622  {
623  assert (isfulluserdata (L, lua_upvalueindex (1)));
624  T const* const t = Userdata::get <T> (L, 1, true);
625  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
626  assert (fnptr != 0);
627  ArgList <Params, 2> args(L);
629  LuaRef v (newTable (L));
630  FuncArgs <Params, 0>::refs (v, args);
631  v.push(L);
632  return 2;
633  }
634  };
635 
636  template <class MemFnPtr, class T,
637  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
639  {
641 
642  static int f (lua_State* L)
643  {
644  assert (isfulluserdata (L, lua_upvalueindex (1)));
645  std::shared_ptr<T>* const t = Userdata::get <std::shared_ptr<T> > (L, 1, false);
646  T* const tt = t->get();
647  if (!tt) {
648  return luaL_error (L, "shared_ptr is nil");
649  }
650  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
651  assert (fnptr != 0);
652  ArgList <Params, 2> args (L);
654  LuaRef v (newTable (L));
655  FuncArgs <Params, 0>::refs (v, args);
656  v.push(L);
657  return 2;
658  }
659  };
660 
661  template <class MemFnPtr, class T,
662  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
664  {
666 
667  static int f (lua_State* L)
668  {
669  assert (isfulluserdata (L, lua_upvalueindex (1)));
670  std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
671  T* const tt = const_cast<T*> (t->get());
672  if (!tt) {
673  return luaL_error (L, "shared_ptr is nil");
674  }
675  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
676  assert (fnptr != 0);
677  ArgList <Params, 2> args (L);
679  LuaRef v (newTable (L));
680  FuncArgs <Params, 0>::refs (v, args);
681  v.push(L);
682  return 2;
683  }
684  };
685 
686  template <class MemFnPtr, class T,
687  class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
689  {
691 
692  static int f (lua_State* L)
693  {
694  assert (isfulluserdata (L, lua_upvalueindex (1)));
695  std::weak_ptr<T>* const tw = Userdata::get <std::weak_ptr<T> > (L, 1, false);
696  std::shared_ptr<T> const t = tw->lock();
697  if (!t) {
698  return luaL_error (L, "cannot lock weak_ptr");
699  }
700  T* const tt = t.get();
701  if (!tt) {
702  return luaL_error (L, "weak_ptr is nil");
703  }
704  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
705  assert (fnptr != 0);
706  ArgList <Params, 2> args (L);
708  LuaRef v (newTable (L));
709  FuncArgs <Params, 0>::refs (v, args);
710  v.push(L);
711  return 2;
712  }
713  };
714 
715  //----------------------------------------------------------------------------
722  template <class MemFnPtr>
723  struct CallMember <MemFnPtr, void>
724  {
727 
728  static int f (lua_State* L)
729  {
730  assert (isfulluserdata (L, lua_upvalueindex (1)));
731  T* const t = Userdata::get <T> (L, 1, false);
732  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
733  assert (fnptr != 0);
734  ArgList <Params, 2> args (L);
735  FuncTraits <MemFnPtr>::call (t, fnptr, args);
736  return 0;
737  }
738  };
739 
740  template <class MemFnPtr>
741  struct CallConstMember <MemFnPtr, void>
742  {
745 
746  static int f (lua_State* L)
747  {
748  assert (isfulluserdata (L, lua_upvalueindex (1)));
749  T const* const t = Userdata::get <T> (L, 1, true);
750  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
751  assert (fnptr != 0);
752  ArgList <Params, 2> args (L);
753  FuncTraits <MemFnPtr>::call (t, fnptr, args);
754  return 0;
755  }
756  };
757 
758  template <class MemFnPtr, class T>
759  struct CallMemberPtr <MemFnPtr, T, void>
760  {
762 
763  static int f (lua_State* L)
764  {
765  assert (isfulluserdata (L, lua_upvalueindex (1)));
766  std::shared_ptr<T>* const t = Userdata::get <std::shared_ptr<T> > (L, 1, false);
767  T* const tt = t->get();
768  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
769  assert (fnptr != 0);
770  ArgList <Params, 2> args (L);
771  FuncTraits <MemFnPtr>::call (tt, fnptr, args);
772  return 0;
773  }
774  };
775 
776  template <class MemFnPtr, class T>
777  struct CallMemberCPtr <MemFnPtr, T, void>
778  {
780 
781  static int f (lua_State* L)
782  {
783  assert (isfulluserdata (L, lua_upvalueindex (1)));
784  std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
785  T* const tt = const_cast<T*> (t->get());
786  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
787  assert (fnptr != 0);
788  ArgList <Params, 2> args (L);
789  FuncTraits <MemFnPtr>::call (tt, fnptr, args);
790  return 0;
791  }
792  };
793 
794  template <class MemFnPtr, class T>
795  struct CallMemberWPtr <MemFnPtr, T, void>
796  {
798 
799  static int f (lua_State* L)
800  {
801  assert (isfulluserdata (L, lua_upvalueindex (1)));
802  std::weak_ptr<T>* const tw = Userdata::get <std::weak_ptr<T> > (L, 1, false);
803  std::shared_ptr<T> const t = tw->lock();
804  if (!t) {
805  return luaL_error (L, "cannot lock weak_ptr");
806  }
807  T* const tt = t.get();
808  if (!tt) {
809  return luaL_error (L, "weak_ptr is nil");
810  }
811  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
812  assert (fnptr != 0);
813  ArgList <Params, 2> args (L);
814  FuncTraits <MemFnPtr>::call (tt, fnptr, args);
815  return 0;
816  }
817  };
818 
819  template <class MemFnPtr>
820  struct CallMemberRef <MemFnPtr, void>
821  {
824 
825  static int f (lua_State* L)
826  {
827  assert (isfulluserdata (L, lua_upvalueindex (1)));
828  T* const t = Userdata::get <T> (L, 1, false);
829  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
830  assert (fnptr != 0);
831  ArgList <Params, 2> args (L);
832  FuncTraits <MemFnPtr>::call (t, fnptr, args);
833  LuaRef v (newTable (L));
834  FuncArgs <Params, 0>::refs (v, args);
835  v.push(L);
836  return 1;
837  }
838  };
839 
840  template <class MemFnPtr>
841  struct CallConstMemberRef <MemFnPtr, void>
842  {
845 
846  static int f (lua_State* L)
847  {
848  assert (isfulluserdata (L, lua_upvalueindex (1)));
849  T const* const t = Userdata::get <T> (L, 1, true);
850  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
851  assert (fnptr != 0);
852  ArgList <Params, 2> args (L);
853  FuncTraits <MemFnPtr>::call (t, fnptr, args);
854  LuaRef v (newTable (L));
855  FuncArgs <Params, 0>::refs (v, args);
856  v.push(L);
857  return 1;
858  }
859  };
860 
861  template <class MemFnPtr, class T>
862  struct CallMemberRefPtr <MemFnPtr, T, void>
863  {
865 
866  static int f (lua_State* L)
867  {
868  assert (isfulluserdata (L, lua_upvalueindex (1)));
869  std::shared_ptr<T>* const t = Userdata::get <std::shared_ptr<T> > (L, 1, false);
870  T* const tt = t->get();
871  if (!tt) {
872  return luaL_error (L, "shared_ptr is nil");
873  }
874  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
875  assert (fnptr != 0);
876  ArgList <Params, 2> args (L);
877  FuncTraits <MemFnPtr>::call (tt, fnptr, args);
878  LuaRef v (newTable (L));
879  FuncArgs <Params, 0>::refs (v, args);
880  v.push(L);
881  return 1;
882  }
883  };
884 
885  template <class MemFnPtr, class T>
886  struct CallMemberRefCPtr <MemFnPtr, T, void>
887  {
889 
890  static int f (lua_State* L)
891  {
892  assert (isfulluserdata (L, lua_upvalueindex (1)));
893  std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
894  T* const tt = const_cast<T*> (t->get());
895  if (!tt) {
896  return luaL_error (L, "shared_ptr is nil");
897  }
898  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
899  assert (fnptr != 0);
900  ArgList <Params, 2> args (L);
901  FuncTraits <MemFnPtr>::call (tt, fnptr, args);
902  LuaRef v (newTable (L));
903  FuncArgs <Params, 0>::refs (v, args);
904  v.push(L);
905  return 1;
906  }
907  };
908 
909  template <class MemFnPtr, class T>
910  struct CallMemberRefWPtr <MemFnPtr, T, void>
911  {
913 
914  static int f (lua_State* L)
915  {
916  assert (isfulluserdata (L, lua_upvalueindex (1)));
917  std::weak_ptr<T>* const tw = Userdata::get <std::weak_ptr<T> > (L, 1, false);
918  std::shared_ptr<T> const t = tw->lock();
919  if (!t) {
920  return luaL_error (L, "cannot lock weak_ptr");
921  }
922  T* const tt = t.get();
923  if (!tt) {
924  return luaL_error (L, "weak_ptr is nil");
925  }
926  MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
927  assert (fnptr != 0);
928  ArgList <Params, 2> args (L);
929  FuncTraits <MemFnPtr>::call (tt, fnptr, args);
930  LuaRef v (newTable (L));
931  FuncArgs <Params, 0>::refs (v, args);
932  v.push(L);
933  return 1;
934  }
935  };
936 
937  //--------------------------------------------------------------------------
944  template <class T>
946  {
947  static int f (lua_State* L)
948  {
949  assert (isfulluserdata (L, lua_upvalueindex (1)));
950  typedef int (T::*MFP)(lua_State* L);
951  T* const t = Userdata::get <T> (L, 1, false);
952  MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
953  assert (fnptr != 0);
954  return (t->*fnptr) (L);
955  }
956  };
957 
958  template <class T>
960  {
961  static int f (lua_State* L)
962  {
963  assert (isfulluserdata (L, lua_upvalueindex (1)));
964  typedef int (T::*MFP)(lua_State* L);
965  T const* const t = Userdata::get <T> (L, 1, true);
966  MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
967  assert (fnptr != 0);
968  return (t->*fnptr) (L);
969  }
970  };
971 
972  //--------------------------------------------------------------------------
973 
974  // SFINAE Helpers
975 
976  template <class MemFnPtr, bool isConst>
978  {
979  static void add (lua_State* L, char const* name, MemFnPtr mf)
980  {
981  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
983  lua_pushvalue (L, -1);
984  rawsetfield (L, -5, name); // const table
985  rawsetfield (L, -3, name); // class table
986  }
987  };
988 
989  template <class MemFnPtr>
990  struct CallMemberFunctionHelper <MemFnPtr, false>
991  {
992  static void add (lua_State* L, char const* name, MemFnPtr mf)
993  {
994  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
996  rawsetfield (L, -3, name); // class table
997  }
998  };
999 
1000  template <class MemFnPtr>
1002  {
1004  static void add (lua_State* L, char const* name, MemFnPtr mf)
1005  {
1006  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1008  rawsetfield (L, -3, name); // class table
1009  }
1010  };
1011 
1012  template <class MemFnPtr>
1014  {
1016  static void add (lua_State* L, char const* name, MemFnPtr mf)
1017  {
1018  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1020  rawsetfield (L, -3, name); // class table
1021  }
1022  };
1023 
1024  template <class MemFnPtr>
1026  {
1028  static void add (lua_State* L, char const* name, MemFnPtr mf)
1029  {
1030  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1032  rawsetfield (L, -3, name); // class table
1033  }
1034  };
1035 
1036  template <class MemFnPtr>
1038  {
1040  static void add (lua_State* L, char const* name, MemFnPtr mf)
1041  {
1042  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1044  rawsetfield (L, -3, name); // class table
1045  }
1046  };
1047 
1048  template <class MemFnPtr>
1050  {
1052  static void add (lua_State* L, char const* name, MemFnPtr mf)
1053  {
1054  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1056  rawsetfield (L, -3, name); // class table
1057  }
1058  };
1059 
1060  template <class MemFnPtr>
1062  {
1064  static void add (lua_State* L, char const* name, MemFnPtr mf)
1065  {
1066  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1068  rawsetfield (L, -3, name); // class table
1069  }
1070  };
1071 
1072  template <class MemFnPtr, bool isConst>
1074  {
1075  static void add (lua_State* L, char const* name, MemFnPtr mf)
1076  {
1077  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1079  lua_pushvalue (L, -1);
1080  rawsetfield (L, -5, name); // const table
1081  rawsetfield (L, -3, name); // class table
1082  }
1083  };
1084 
1085  template <class MemFnPtr>
1086  struct CallMemberRefFunctionHelper <MemFnPtr, false>
1087  {
1088  static void add (lua_State* L, char const* name, MemFnPtr mf)
1089  {
1090  new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
1092  rawsetfield (L, -3, name); // class table
1093  }
1094  };
1095 
1096  //--------------------------------------------------------------------------
1100  template <class C>
1101  static int gcMetaMethod (lua_State* L)
1102  {
1103  Userdata* const ud = Userdata::getExact <C> (L, 1);
1104  ud->~Userdata ();
1105  return 0;
1106  }
1107 
1108  static int gcNOOPMethod (lua_State* L)
1109  {
1110  return 0;
1111  }
1112 
1113  //--------------------------------------------------------------------------
1120  template <class C, typename T>
1121  static int getProperty (lua_State* L)
1122  {
1123  C const* const c = Userdata::get <C> (L, 1, true);
1124  T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
1125  Stack <T>::push (L, c->**mp);
1126  return 1;
1127  }
1128 
1129  //--------------------------------------------------------------------------
1130 
1134  template <typename U>
1135  static int getConst (lua_State* L)
1136  {
1137  U *v = static_cast <U *> (lua_touserdata (L, lua_upvalueindex (1)));
1138  assert (v);
1139  Stack <U>::push (L, *v);
1140  return 1;
1141  }
1142 
1143  //--------------------------------------------------------------------------
1150  template <class C, typename T>
1151  static int setProperty (lua_State* L)
1152  {
1153  C* const c = Userdata::get <C> (L, 1, false);
1154  T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
1155  c->**mp = Stack <T>::get (L, 2);
1156  return 0;
1157  }
1158 
1159  //--------------------------------------------------------------------------
1160 
1161  // metatable callback for "array[index]"
1162  template <typename T>
1163  static int array_index (lua_State* L) {
1164  T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
1165  int const index = luabridge::Stack<int>::get (L, 2);
1166  assert (index > 0);
1167  luabridge::Stack<T>::push (L, (*parray)[index-1]);
1168  return 1;
1169  }
1170 
1171  // metatable callback for "array[index] = value"
1172  template <typename T>
1173  static int array_newindex (lua_State* L) {
1174  T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
1175  int const index = luabridge::Stack<int>::get (L, 2);
1176  T const value = luabridge::Stack<T>::get (L, 3);
1177  assert (index > 0);
1178  (*parray)[index-1] = value;
1179  return 0;
1180  }
1181 
1182  template <typename T>
1183  static int getArray (lua_State* L) {
1184  T *v = luabridge::Stack<T*>::get (L, 1);
1185  T** parray = (T**) lua_newuserdata(L, sizeof(T**));
1186  *parray = v;
1187  luaL_getmetatable(L, typeid(T).name());
1188  lua_setmetatable(L, -2);
1189  return 1;
1190  }
1191 
1192  // copy complete c array to lua table
1193  template <typename T>
1194  static int getTable (lua_State* L) {
1195  T *v = luabridge::Stack<T*>::get (L, 1);
1196  const int cnt = luabridge::Stack<int>::get (L, 2);
1197  LuaRef t (L);
1198  t = newTable (L);
1199  for (int i = 0; i < cnt; ++i) {
1200  t[i + 1] = v[i];
1201  }
1202  t.push(L);
1203  return 1;
1204  }
1205 
1206  // copy lua table to c array
1207  template <typename T>
1208  static int setTable (lua_State* L) {
1209  T *v = luabridge::Stack<T*>::get (L, 1);
1210  LuaRef t (LuaRef::fromStack(L, 2));
1211  const int cnt = luabridge::Stack<int>::get (L, 3);
1212  for (int i = 0; i < cnt; ++i) {
1213  v[i] = t[i + 1];
1214  }
1215  return 0;
1216  }
1217 
1218  // return same array at an offset
1219  template <typename T>
1220  static int offsetArray (lua_State* L) {
1221  T *v = luabridge::Stack<T*>::get (L, 1);
1222  const unsigned int i = luabridge::Stack<unsigned int>::get (L, 2);
1223  Stack <T*>::push (L, &v[i]);
1224  return 1;
1225  }
1226 
1227  //--------------------------------------------------------------------------
1232  // read lua table into C++ std::list
1233  template <class T, class C>
1234  static int tableToListHelper (lua_State *L, C * const t)
1235  {
1236  if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1237  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1238  lua_pushvalue (L, -1);
1239  lua_pushnil (L);
1240  while (lua_next (L, -2)) {
1241 #if 0
1242  lua_pushvalue (L, -2);
1243  lua_pop (L, 1);
1244 #endif
1245  // lua_gettop is used because Userdata::getClass() doesn't handle negative stack indexes.
1246  T const value = Stack<T>::get (L, lua_gettop (L));
1247  t->push_back (value);
1248  lua_pop (L, 1);
1249  }
1250  lua_pop (L, 1);
1251  lua_pop (L, 2);
1252  Stack<C>::push (L, *t);
1253  return 1;
1254  }
1255 
1256  template <class T, class C>
1257  static int tableToList (lua_State *L)
1258  {
1259  C * const t = Userdata::get<C> (L, 1, false);
1260  return tableToListHelper<T, C> (L, t);
1261  }
1262 
1263  template <class T, class C>
1264  static int ptrTableToList (lua_State *L)
1265  {
1266  std::shared_ptr<C> const* const t = Userdata::get<std::shared_ptr<C> > (L, 1, true);
1267  if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1268  return tableToListHelper<T, C> (L, t->get());
1269  }
1270  //--------------------------------------------------------------------------
1271 
1272 
1273  template <class T, class C>
1274  static int vectorToArray (lua_State *L)
1275  {
1276  C * const t = Userdata::get<C> (L, 1, false);
1277  T * a = &((*t)[0]);
1278  Stack <T*>::push (L, a);
1279  return 1;
1280  }
1281 
1282  //--------------------------------------------------------------------------
1283  template <class T, class C>
1284  static int listIterIter (lua_State *L) {
1285  typedef typename C::const_iterator IterType;
1286  IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1287  IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1288  assert (end);
1289  assert (iter);
1290  if ((*iter) == (*end)) {
1291  return 0;
1292  }
1293  Stack <T>::push (L, **iter);
1294  ++(*iter);
1295  return 1;
1296  }
1297 
1298  // generate an iterator
1299  template <class T, class C>
1300  static int listIterHelper (lua_State *L, C const * const t)
1301  {
1302  if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1303  typedef typename C::const_iterator IterType;
1304  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1305  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1306  lua_pushcclosure (L, listIterIter<T, C>, 2);
1307  return 1;
1308  }
1309 
1310  template <class T, class C>
1311  static int listIter (lua_State *L)
1312  {
1313  C const * const t = Userdata::get <C> (L, 1, true);
1314  return listIterHelper<T, C> (L, t);
1315  }
1316 
1317  template <class T, class C>
1318  static int ptrListIter (lua_State *L)
1319  {
1320  std::shared_ptr<C> const* const t = Userdata::get <std::shared_ptr<C> >(L, 1, true);
1321  if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1322  return listIterHelper<T, C> (L, t->get());
1323  }
1324 
1325  //--------------------------------------------------------------------------
1326  // generate table from std::list
1327  template <class T, class C>
1328  static int listToTableHelper (lua_State *L, C const* const t)
1329  {
1330  if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1331 #if 0 // direct lua api
1332  lua_createtable(L, t->size(), 0);
1333  int newTable = lua_gettop(L);
1334  int index = 1;
1335  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1336  Stack<T>::push(L, (*iter));
1337  lua_rawseti (L, newTable, index);
1338  }
1339 #else // luabridge way
1340  LuaRef v (L);
1341  v = newTable (L);
1342  int index = 1;
1343  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1344  v[index] = (*iter);
1345  }
1346  v.push(L);
1347 #endif
1348  return 1;
1349  }
1350 
1351  template <class T, class C>
1352  static int listToTable (lua_State *L)
1353  {
1354  C const* const t = Userdata::get <C> (L, 1, true);
1355  return listToTableHelper<T, C> (L, t);
1356  }
1357 
1358  template <class T, class C>
1359  static int ptrListToTable (lua_State *L)
1360  {
1361  std::shared_ptr<C> const* const t = Userdata::get <std::shared_ptr<C> > (L, 1, true);
1362  if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1363  return listToTableHelper<T, C> (L, t->get());
1364  }
1365 
1366  //--------------------------------------------------------------------------
1367  // push back a C-pointer to a std::list<T*>
1368 
1369  template <class T, class C>
1370  static int pushbackptr (lua_State *L)
1371  {
1372  C * const c = Userdata::get <C> (L, 1, false);
1373  if (!c) { return luaL_error (L, "invalid pointer to std::list<>"); }
1374  T * const v = Userdata::get <T> (L, 2, true);
1375  if (!v) { return luaL_error (L, "invalid pointer to std::list<>::value_type"); }
1376  c->push_back (v);
1377  return 0;
1378  }
1379 
1380  //--------------------------------------------------------------------------
1381  // generate std::map from table
1382 
1383  template <class K, class V>
1384  static int tableToMap (lua_State *L)
1385  {
1386  typedef std::map<K, V> C;
1387  C * const t = Userdata::get <C> (L, 1, true);
1388  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1389  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1390 
1391  lua_pushvalue (L, -1);
1392  lua_pushnil (L);
1393  while (lua_next (L, -2)) {
1394  lua_pushvalue (L, -2);
1395  // lua_gettop is used because Userdata::getClass() doesn't handle negative stack indexes.
1396  K const key = Stack<K>::get (L, lua_gettop (L));
1397  lua_pop (L, 1);
1398  V const value = Stack<V>::get (L, lua_gettop (L));
1399  lua_pop (L, 1);
1400  t->insert (std::pair<K,V> (key, value));
1401  //(*t)[key] = value;
1402  }
1403  lua_pop (L, 1);
1404  lua_pop (L, 2);
1405  Stack<C>::push (L, *t);
1406  return 1;
1407  }
1408 
1409  // iterate over a std::map
1410  template <class K, class V>
1411  static int mapIterIter (lua_State *L)
1412  {
1413  typedef std::map<K, V> C;
1414  typedef typename C::const_iterator IterType;
1415  IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1416  IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1417  assert (end);
1418  assert (iter);
1419  if ((*iter) == (*end)) {
1420  return 0;
1421  }
1422  Stack <K>::push (L, (*iter)->first);
1423  Stack <V>::push (L, (*iter)->second);
1424  ++(*iter);
1425  return 2;
1426  }
1427 
1428  // generate iterator
1429  template <class K, class V>
1430  static int mapIter (lua_State *L)
1431  {
1432  typedef std::map<K, V> C;
1433  C const * const t = Userdata::get <C> (L, 1, true);
1434  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1435  typedef typename C::const_iterator IterType;
1436  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1437  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1438  lua_pushcclosure (L, mapIterIter<K, V>, 2);
1439  return 1;
1440  }
1441 
1442  // generate table from std::map
1443  template <class K, class V>
1444  static int mapToTable (lua_State *L)
1445  {
1446  typedef std::map<K, V> C;
1447  C const* const t = Userdata::get <C> (L, 1, true);
1448  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1449 
1450  LuaRef v (L);
1451  v = newTable (L);
1452  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1453  v[(*iter).first] = (*iter).second;
1454  }
1455  v.push(L);
1456  return 1;
1457  }
1458 
1459  // generate table from std::map
1460  template <class K, class V>
1461  static int mapAt (lua_State *L)
1462  {
1463  typedef std::map<K, V> C;
1464  C const* const t = Userdata::get <C> (L, 1, true);
1465  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1466  K const key = Stack<K>::get (L, 2);
1467  typename C::const_iterator iter = t->find(key);
1468  if (iter == t->end()) {
1469  return 0;
1470  }
1471  Stack <V>::push (L, (*iter).second);
1472  return 1;
1473  }
1474 
1475 
1476  //--------------------------------------------------------------------------
1477  // generate std::set from table keys ( table[member] = true )
1478  // http://www.lua.org/pil/11.5.html
1479 
1480  template <class T, class C>
1481  static int tableToSet (lua_State *L)
1482  {
1483  C * const t = Userdata::get <C> (L, 1, true);
1484  if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1485  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1486 
1487  lua_pushvalue (L, -1);
1488  lua_pushnil (L);
1489  while (lua_next (L, -2)) {
1490  lua_pushvalue (L, -2);
1491  // lua_gettop is used because Userdata::getClass() doesn't handle negative stack indexes.
1492  T const member = Stack<T>::get (L, lua_gettop (L));
1493  lua_pop (L, 1);
1494  bool const v = Stack<bool>::get (L, lua_gettop (L));
1495  lua_pop (L, 1);
1496  if (v) {
1497  t->insert (member);
1498  }
1499  }
1500  lua_pop (L, 1);
1501  lua_pop (L, 2);
1502  Stack<C>::push (L, *t);
1503  return 1;
1504  }
1505 
1506  // iterate over a std::set, explicit "true" value.
1507  // compare to http://www.lua.org/pil/11.5.html
1508  template <class T, class C>
1509  static int setIterIter (lua_State *L)
1510  {
1511  typedef typename C::const_iterator IterType;
1512  IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1513  IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1514  assert (end);
1515  assert (iter);
1516  if ((*iter) == (*end)) {
1517  return 0;
1518  }
1519  Stack <T>::push (L, **iter);
1520  Stack <bool>::push (L, true);
1521  ++(*iter);
1522  return 2;
1523  }
1524 
1525  template <class T, class C>
1526  static int setInsert (lua_State *L)
1527  {
1528  C* const t = Userdata::get <C> (L, 1, false);
1529  T const * const v = Userdata::get <T> (L, 2, true);
1530  auto rv = t->insert (*v);
1531  Stack <bool>::push (L, rv.second);
1532  return 1;
1533  }
1534 
1535  // generate iterator
1536  template <class T, class C>
1537  static int setIter (lua_State *L)
1538  {
1539  C const * const t = Userdata::get <C> (L, 1, true);
1540  if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1541  typedef typename C::const_iterator IterType;
1542  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1543  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1544  lua_pushcclosure (L, setIterIter<T, C>, 2);
1545  return 1;
1546  }
1547 
1548  // generate table from std::set
1549  template <class T, class C>
1550  static int setToTable (lua_State *L)
1551  {
1552  C const* const t = Userdata::get <C> (L, 1, true);
1553  if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1554 
1555  LuaRef v (L);
1556  v = newTable (L);
1557  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1558  v[(*iter)] = true;
1559  }
1560  v.push(L);
1561  return 1;
1562  }
1563 
1564  //--------------------------------------------------------------------------
1565  // bitset { num = true }
1566  // compare to http://www.lua.org/pil/11.5.html
1567  template <unsigned int T>
1568  static int tableToBitSet (lua_State *L)
1569  {
1570  typedef std::bitset<T> C;
1571  C * const t = Userdata::get <C> (L, 1, true);
1572  if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1573  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1574 
1575  lua_pushvalue (L, -1);
1576  lua_pushnil (L);
1577  while (lua_next (L, -2)) {
1578  lua_pushvalue (L, -2);
1579  unsigned int const member = Stack<unsigned int>::get (L, -1);
1580  bool const v = Stack<bool>::get (L, -2);
1581  if (member < T && v) {
1582  t->set (member);
1583  }
1584  lua_pop (L, 2);
1585  }
1586  lua_pop (L, 1);
1587  lua_pop (L, 2);
1588  Stack<C>::push (L, *t);
1589  return 1;
1590  }
1591 
1592  // generate table from std::bitset
1593  template <unsigned int T>
1594  static int bitSetToTable (lua_State *L)
1595  {
1596  typedef std::bitset<T> C;
1597  C const* const t = Userdata::get <C> (L, 1, true);
1598  if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1599 
1600  LuaRef v (L);
1601  v = newTable (L);
1602  for (unsigned int i = 0; i < T; ++i) {
1603  if (t->test (i)) {
1604  v[i] = true;
1605  }
1606  }
1607  v.push(L);
1608  return 1;
1609  }
1610 
1611 };
1612 
1613 /* vim: set et sw=2: */
bool isfulluserdata(lua_State *L, int index)
Definition: LuaHelpers.h:127
void rawsetfield(lua_State *L, int index, char const *key)
Definition: LuaHelpers.h:116
void rawgetfield(lua_State *L, int index, char const *key)
Definition: LuaHelpers.h:106
LuaRef newTable(lua_State *L)
Definition: LuaRef.h:1193
Definition: LuaRef.h:52
static LuaRef fromStack(lua_State *L, int index)
Definition: LuaRef.h:671
void push(lua_State *L) const
Definition: LuaRef.h:813
virtual ~Userdata()
Definition: Userdata.h:304
GtkImageIconNameData name
Definition: gtkimage.h:6
int() luaL_error(lua_State *L, const char *fmt,...)
#define luaL_getmetatable(L, n)
Definition: lauxlib.h:135
void *() luaL_checkudata(lua_State *L, int ud, const char *tname)
#define lua_istable(L, n)
int() lua_rawget(lua_State *L, int idx)
int() lua_iscfunction(lua_State *L, int idx)
void() lua_createtable(lua_State *L, int narr, int nrec)
void() lua_pushvalue(lua_State *L, int idx)
#define lua_islightuserdata(L, n)
int() lua_setmetatable(lua_State *L, int objindex)
int() lua_next(lua_State *L, int idx)
void *() lua_newuserdata(lua_State *L, size_t sz)
void() lua_rawseti(lua_State *L, int idx, lua_Integer n)
#define lua_remove(L, idx)
void *() lua_touserdata(lua_State *L, int idx)
#define lua_isnil(L, n)
#define lua_call(L, n, r)
int() lua_gettop(lua_State *L)
void() lua_pushnil(lua_State *L)
#define lua_pop(L, n)
#define lua_upvalueindex(i)
Definition: lua-5.3.5/lua.h:43
int() lua_getmetatable(lua_State *L, int objindex)
#define lua_tostring(L, i)
void() lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
void push(lua_State *L, T t)
Definition: LuaBridge.h:159
static int f(lua_State *L)
Definition: CFunctions.h:961
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:843
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:844
static int f(lua_State *L)
Definition: CFunctions.h:621
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:619
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:618
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:744
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:743
static int f(lua_State *L)
Definition: CFunctions.h:324
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:322
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:321
static int f(lua_State *L)
Definition: CFunctions.h:947
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:1027
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1028
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:779
static int f(lua_State *L)
Definition: CFunctions.h:364
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:362
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:992
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:979
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:1003
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1004
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:761
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:340
static int f(lua_State *L)
Definition: CFunctions.h:342
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:1039
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1040
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:888
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:665
static int f(lua_State *L)
Definition: CFunctions.h:667
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1088
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1075
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1016
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:1015
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:864
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:640
static int f(lua_State *L)
Definition: CFunctions.h:642
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:1063
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1064
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:912
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:690
static int f(lua_State *L)
Definition: CFunctions.h:692
static int f(lua_State *L)
Definition: CFunctions.h:825
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:822
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:823
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:597
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:596
static int f(lua_State *L)
Definition: CFunctions.h:599
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:1051
static void add(lua_State *L, char const *name, MemFnPtr mf)
Definition: CFunctions.h:1052
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:797
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:567
static int f(lua_State *L)
Definition: CFunctions.h:569
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:725
static int f(lua_State *L)
Definition: CFunctions.h:728
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:726
FuncTraits< MemFnPtr >::Params Params
Definition: CFunctions.h:303
static int f(lua_State *L)
Definition: CFunctions.h:305
FuncTraits< MemFnPtr >::ClassType T
Definition: CFunctions.h:302
static int f(lua_State *L)
Definition: CFunctions.h:276
FuncTraits< FnPtr >::Params Params
Definition: CFunctions.h:275
static int f(lua_State *L)
Definition: CFunctions.h:258
FuncTraits< FnPtr >::Params Params
Definition: CFunctions.h:257
FuncTraits< FnPtr >::Params Params
Definition: CFunctions.h:237
static int f(lua_State *L)
Definition: CFunctions.h:238
FuncTraits< FnPtr >::Params Params
Definition: CFunctions.h:213
static int f(lua_State *L)
Definition: CFunctions.h:214
static int f(lua_State *L)
Definition: CFunctions.h:406
static int f(lua_State *L)
Definition: CFunctions.h:417
static int f(lua_State *L)
Definition: CFunctions.h:383
static int f(lua_State *L)
Definition: CFunctions.h:394
static int f(lua_State *L)
Definition: CFunctions.h:456
static int f(lua_State *L)
Definition: CFunctions.h:428
static int f(lua_State *L)
Definition: CFunctions.h:468
static int f(lua_State *L)
Definition: CFunctions.h:439
static int mapIter(lua_State *L)
Definition: CFunctions.h:1430
static int newindexMetaMethod(lua_State *L)
Definition: CFunctions.h:107
static int offsetArray(lua_State *L)
Definition: CFunctions.h:1220
static int readOnlyError(lua_State *L)
Definition: CFunctions.h:155
static int setTable(lua_State *L)
Definition: CFunctions.h:1208
static int listIterIter(lua_State *L)
Definition: CFunctions.h:1284
static int setInsert(lua_State *L)
Definition: CFunctions.h:1526
static int tableToSet(lua_State *L)
Definition: CFunctions.h:1481
static int getVariable(lua_State *L)
Definition: CFunctions.h:173
static int setVariable(lua_State *L)
Definition: CFunctions.h:191
static int listToTableHelper(lua_State *L, C const *const t)
Definition: CFunctions.h:1328
static int tableToList(lua_State *L)
Definition: CFunctions.h:1257
static int getWPtrProperty(lua_State *L)
Definition: CFunctions.h:517
static int setToTable(lua_State *L)
Definition: CFunctions.h:1550
static int listIter(lua_State *L)
Definition: CFunctions.h:1311
static int indexMetaMethod(lua_State *L)
Definition: CFunctions.h:43
static int tableToMap(lua_State *L)
Definition: CFunctions.h:1384
static int getProperty(lua_State *L)
Definition: CFunctions.h:1121
static int getArray(lua_State *L)
Definition: CFunctions.h:1183
static int array_index(lua_State *L)
Definition: CFunctions.h:1163
static int mapIterIter(lua_State *L)
Definition: CFunctions.h:1411
static int getPtrProperty(lua_State *L)
Definition: CFunctions.h:504
static int setPtrProperty(lua_State *L)
Definition: CFunctions.h:534
static int setIter(lua_State *L)
Definition: CFunctions.h:1537
static int listToTable(lua_State *L)
Definition: CFunctions.h:1352
static int ptrListToTable(lua_State *L)
Definition: CFunctions.h:1359
static int ptrTableToList(lua_State *L)
Definition: CFunctions.h:1264
static int bitSetToTable(lua_State *L)
Definition: CFunctions.h:1594
static int gcMetaMethod(lua_State *L)
Definition: CFunctions.h:1101
static int tableToBitSet(lua_State *L)
Definition: CFunctions.h:1568
static int mapToTable(lua_State *L)
Definition: CFunctions.h:1444
static int getConst(lua_State *L)
Definition: CFunctions.h:1135
static int vectorToArray(lua_State *L)
Definition: CFunctions.h:1274
static int getTable(lua_State *L)
Definition: CFunctions.h:1194
static int tableToListHelper(lua_State *L, C *const t)
Definition: CFunctions.h:1234
static int setIterIter(lua_State *L)
Definition: CFunctions.h:1509
static int pushbackptr(lua_State *L)
Definition: CFunctions.h:1370
static int setProperty(lua_State *L)
Definition: CFunctions.h:1151
static int ptrListIter(lua_State *L)
Definition: CFunctions.h:1318
static int gcNOOPMethod(lua_State *L)
Definition: CFunctions.h:1108
static int array_newindex(lua_State *L)
Definition: CFunctions.h:1173
static int setWPtrProperty(lua_State *L)
Definition: CFunctions.h:547
static int listIterHelper(lua_State *L, C const *const t)
Definition: CFunctions.h:1300
static int mapAt(lua_State *L)
Definition: CFunctions.h:1461
static std::conditional_t< passByValueNotEnum, T const &, T > get(lua_State *L, int index)
Definition: Userdata.h:667
static void push(lua_State *L, T const &t)
Definition: Userdata.h:646