Ardour  8.7-14-g57a6773833
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  lua_pushvalue (L, -2);
1242  T const value = Stack<T>::get (L, -2);
1243  t->push_back (value);
1244  lua_pop (L, 2);
1245  }
1246  lua_pop (L, 1);
1247  lua_pop (L, 2);
1248  Stack<C>::push (L, *t);
1249  return 1;
1250  }
1251 
1252  template <class T, class C>
1253  static int tableToList (lua_State *L)
1254  {
1255  C * const t = Userdata::get<C> (L, 1, false);
1256  return tableToListHelper<T, C> (L, t);
1257  }
1258 
1259  template <class T, class C>
1260  static int ptrTableToList (lua_State *L)
1261  {
1262  std::shared_ptr<C> const* const t = Userdata::get<std::shared_ptr<C> > (L, 1, true);
1263  if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1264  return tableToListHelper<T, C> (L, t->get());
1265  }
1266  //--------------------------------------------------------------------------
1267 
1268 
1269  template <class T, class C>
1270  static int vectorToArray (lua_State *L)
1271  {
1272  C * const t = Userdata::get<C> (L, 1, false);
1273  T * a = &((*t)[0]);
1274  Stack <T*>::push (L, a);
1275  return 1;
1276  }
1277 
1278  //--------------------------------------------------------------------------
1279  template <class T, class C>
1280  static int listIterIter (lua_State *L) {
1281  typedef typename C::const_iterator IterType;
1282  IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1283  IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1284  assert (end);
1285  assert (iter);
1286  if ((*iter) == (*end)) {
1287  return 0;
1288  }
1289  Stack <T>::push (L, **iter);
1290  ++(*iter);
1291  return 1;
1292  }
1293 
1294  // generate an iterator
1295  template <class T, class C>
1296  static int listIterHelper (lua_State *L, C const * const t)
1297  {
1298  if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1299  typedef typename C::const_iterator IterType;
1300  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1301  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1302  lua_pushcclosure (L, listIterIter<T, C>, 2);
1303  return 1;
1304  }
1305 
1306  template <class T, class C>
1307  static int listIter (lua_State *L)
1308  {
1309  C const * const t = Userdata::get <C> (L, 1, true);
1310  return listIterHelper<T, C> (L, t);
1311  }
1312 
1313  template <class T, class C>
1314  static int ptrListIter (lua_State *L)
1315  {
1316  std::shared_ptr<C> const* const t = Userdata::get <std::shared_ptr<C> >(L, 1, true);
1317  if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1318  return listIterHelper<T, C> (L, t->get());
1319  }
1320 
1321  //--------------------------------------------------------------------------
1322  // generate table from std::list
1323  template <class T, class C>
1324  static int listToTableHelper (lua_State *L, C const* const t)
1325  {
1326  if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1327 #if 0 // direct lua api
1328  lua_createtable(L, t->size(), 0);
1329  int newTable = lua_gettop(L);
1330  int index = 1;
1331  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1332  Stack<T>::push(L, (*iter));
1333  lua_rawseti (L, newTable, index);
1334  }
1335 #else // luabridge way
1336  LuaRef v (L);
1337  v = newTable (L);
1338  int index = 1;
1339  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1340  v[index] = (*iter);
1341  }
1342  v.push(L);
1343 #endif
1344  return 1;
1345  }
1346 
1347  template <class T, class C>
1348  static int listToTable (lua_State *L)
1349  {
1350  C const* const t = Userdata::get <C> (L, 1, true);
1351  return listToTableHelper<T, C> (L, t);
1352  }
1353 
1354  template <class T, class C>
1355  static int ptrListToTable (lua_State *L)
1356  {
1357  std::shared_ptr<C> const* const t = Userdata::get <std::shared_ptr<C> > (L, 1, true);
1358  if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1359  return listToTableHelper<T, C> (L, t->get());
1360  }
1361 
1362  //--------------------------------------------------------------------------
1363  // push back a C-pointer to a std::list<T*>
1364 
1365  template <class T, class C>
1366  static int pushbackptr (lua_State *L)
1367  {
1368  C * const c = Userdata::get <C> (L, 1, false);
1369  if (!c) { return luaL_error (L, "invalid pointer to std::list<>"); }
1370  T * const v = Userdata::get <T> (L, 2, true);
1371  if (!v) { return luaL_error (L, "invalid pointer to std::list<>::value_type"); }
1372  c->push_back (v);
1373  return 0;
1374  }
1375 
1376  //--------------------------------------------------------------------------
1377  // generate std::map from table
1378 
1379  template <class K, class V>
1380  static int tableToMap (lua_State *L)
1381  {
1382  typedef std::map<K, V> C;
1383  C * const t = Userdata::get <C> (L, 1, true);
1384  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1385  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1386 
1387  lua_pushvalue (L, -1);
1388  lua_pushnil (L);
1389  while (lua_next (L, -2)) {
1390  lua_pushvalue (L, -2);
1391  K const key = Stack<K>::get (L, -1);
1392  V const value = Stack<V>::get (L, -2);
1393  t->insert (std::pair<K,V> (key, value));
1394  //(*t)[key] = value;
1395  lua_pop (L, 2);
1396  }
1397  lua_pop (L, 1);
1398  lua_pop (L, 2);
1399  Stack<C>::push (L, *t);
1400  return 1;
1401  }
1402 
1403  // iterate over a std::map
1404  template <class K, class V>
1405  static int mapIterIter (lua_State *L)
1406  {
1407  typedef std::map<K, V> C;
1408  typedef typename C::const_iterator IterType;
1409  IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1410  IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1411  assert (end);
1412  assert (iter);
1413  if ((*iter) == (*end)) {
1414  return 0;
1415  }
1416  Stack <K>::push (L, (*iter)->first);
1417  Stack <V>::push (L, (*iter)->second);
1418  ++(*iter);
1419  return 2;
1420  }
1421 
1422  // generate iterator
1423  template <class K, class V>
1424  static int mapIter (lua_State *L)
1425  {
1426  typedef std::map<K, V> C;
1427  C const * const t = Userdata::get <C> (L, 1, true);
1428  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1429  typedef typename C::const_iterator IterType;
1430  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1431  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1432  lua_pushcclosure (L, mapIterIter<K, V>, 2);
1433  return 1;
1434  }
1435 
1436  // generate table from std::map
1437  template <class K, class V>
1438  static int mapToTable (lua_State *L)
1439  {
1440  typedef std::map<K, V> C;
1441  C const* const t = Userdata::get <C> (L, 1, true);
1442  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1443 
1444  LuaRef v (L);
1445  v = newTable (L);
1446  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1447  v[(*iter).first] = (*iter).second;
1448  }
1449  v.push(L);
1450  return 1;
1451  }
1452 
1453  // generate table from std::map
1454  template <class K, class V>
1455  static int mapAt (lua_State *L)
1456  {
1457  typedef std::map<K, V> C;
1458  C const* const t = Userdata::get <C> (L, 1, true);
1459  if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1460  K const key = Stack<K>::get (L, 2);
1461  typename C::const_iterator iter = t->find(key);
1462  if (iter == t->end()) {
1463  return 0;
1464  }
1465  Stack <V>::push (L, (*iter).second);
1466  return 1;
1467  }
1468 
1469 
1470  //--------------------------------------------------------------------------
1471  // generate std::set from table keys ( table[member] = true )
1472  // http://www.lua.org/pil/11.5.html
1473 
1474  template <class T, class C>
1475  static int tableToSet (lua_State *L)
1476  {
1477  C * const t = Userdata::get <C> (L, 1, true);
1478  if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1479  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1480 
1481  lua_pushvalue (L, -1);
1482  lua_pushnil (L);
1483  while (lua_next (L, -2)) {
1484  lua_pushvalue (L, -2);
1485  T const member = Stack<T>::get (L, -1);
1486  bool const v = Stack<bool>::get (L, -2);
1487  if (v) {
1488  t->insert (member);
1489  }
1490  lua_pop (L, 2);
1491  }
1492  lua_pop (L, 1);
1493  lua_pop (L, 2);
1494  Stack<C>::push (L, *t);
1495  return 1;
1496  }
1497 
1498  // iterate over a std::set, explicit "true" value.
1499  // compare to http://www.lua.org/pil/11.5.html
1500  template <class T, class C>
1501  static int setIterIter (lua_State *L)
1502  {
1503  typedef typename C::const_iterator IterType;
1504  IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1505  IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1506  assert (end);
1507  assert (iter);
1508  if ((*iter) == (*end)) {
1509  return 0;
1510  }
1511  Stack <T>::push (L, **iter);
1512  Stack <bool>::push (L, true);
1513  ++(*iter);
1514  return 2;
1515  }
1516 
1517  template <class T, class C>
1518  static int setInsert (lua_State *L)
1519  {
1520  C* const t = Userdata::get <C> (L, 1, false);
1521  T const * const v = Userdata::get <T> (L, 2, true);
1522  auto rv = t->insert (*v);
1523  Stack <bool>::push (L, rv.second);
1524  return 1;
1525  }
1526 
1527  // generate iterator
1528  template <class T, class C>
1529  static int setIter (lua_State *L)
1530  {
1531  C const * const t = Userdata::get <C> (L, 1, true);
1532  if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1533  typedef typename C::const_iterator IterType;
1534  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1535  new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1536  lua_pushcclosure (L, setIterIter<T, C>, 2);
1537  return 1;
1538  }
1539 
1540  // generate table from std::set
1541  template <class T, class C>
1542  static int setToTable (lua_State *L)
1543  {
1544  C const* const t = Userdata::get <C> (L, 1, true);
1545  if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1546 
1547  LuaRef v (L);
1548  v = newTable (L);
1549  for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1550  v[(*iter)] = true;
1551  }
1552  v.push(L);
1553  return 1;
1554  }
1555 
1556  //--------------------------------------------------------------------------
1557  // bitset { num = true }
1558  // compare to http://www.lua.org/pil/11.5.html
1559  template <unsigned int T>
1560  static int tableToBitSet (lua_State *L)
1561  {
1562  typedef std::bitset<T> C;
1563  C * const t = Userdata::get <C> (L, 1, true);
1564  if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1565  if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1566 
1567  lua_pushvalue (L, -1);
1568  lua_pushnil (L);
1569  while (lua_next (L, -2)) {
1570  lua_pushvalue (L, -2);
1571  unsigned int const member = Stack<unsigned int>::get (L, -1);
1572  bool const v = Stack<bool>::get (L, -2);
1573  if (member < T && v) {
1574  t->set (member);
1575  }
1576  lua_pop (L, 2);
1577  }
1578  lua_pop (L, 1);
1579  lua_pop (L, 2);
1580  Stack<C>::push (L, *t);
1581  return 1;
1582  }
1583 
1584  // generate table from std::bitset
1585  template <unsigned int T>
1586  static int bitSetToTable (lua_State *L)
1587  {
1588  typedef std::bitset<T> C;
1589  C const* const t = Userdata::get <C> (L, 1, true);
1590  if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1591 
1592  LuaRef v (L);
1593  v = newTable (L);
1594  for (unsigned int i = 0; i < T; ++i) {
1595  if (t->test (i)) {
1596  v[i] = true;
1597  }
1598  }
1599  v.push(L);
1600  return 1;
1601  }
1602 
1603 };
1604 
1605 /* 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:160
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:1424
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:1280
static int setInsert(lua_State *L)
Definition: CFunctions.h:1518
static int tableToSet(lua_State *L)
Definition: CFunctions.h:1475
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:1324
static int tableToList(lua_State *L)
Definition: CFunctions.h:1253
static int getWPtrProperty(lua_State *L)
Definition: CFunctions.h:517
static int setToTable(lua_State *L)
Definition: CFunctions.h:1542
static int listIter(lua_State *L)
Definition: CFunctions.h:1307
static int indexMetaMethod(lua_State *L)
Definition: CFunctions.h:43
static int tableToMap(lua_State *L)
Definition: CFunctions.h:1380
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:1405
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:1529
static int listToTable(lua_State *L)
Definition: CFunctions.h:1348
static int ptrListToTable(lua_State *L)
Definition: CFunctions.h:1355
static int ptrTableToList(lua_State *L)
Definition: CFunctions.h:1260
static int bitSetToTable(lua_State *L)
Definition: CFunctions.h:1586
static int gcMetaMethod(lua_State *L)
Definition: CFunctions.h:1101
static int tableToBitSet(lua_State *L)
Definition: CFunctions.h:1560
static int mapToTable(lua_State *L)
Definition: CFunctions.h:1438
static int getConst(lua_State *L)
Definition: CFunctions.h:1135
static int vectorToArray(lua_State *L)
Definition: CFunctions.h:1270
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:1501
static int pushbackptr(lua_State *L)
Definition: CFunctions.h:1366
static int setProperty(lua_State *L)
Definition: CFunctions.h:1151
static int ptrListIter(lua_State *L)
Definition: CFunctions.h:1314
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:1296
static int mapAt(lua_State *L)
Definition: CFunctions.h:1455
static T get(lua_State *L, int index)
Definition: Userdata.h:722
static void push(lua_State *L, T const &t)
Definition: Userdata.h:715