Previous 199869 Revisions Next

r31046 Friday 20th June, 2014 at 12:15:24 UTC by Miodrag Milanović
Added LuaBridge and exposed few classes as example (nw)
[src/emu]luaengine.c luaengine.h
[src/lib/lua/bridge]LuaBridge.h*
[src/lib/lua/bridge/detail]CFunctions.h* ClassInfo.h* Constructor.h* FuncTraits.h* Iterator.h* LuaException.h* LuaHelpers.h* LuaRef.h* Namespace.h* Stack.h* TypeList.h* TypeTraits.h* Userdata.h* dump.h*

trunk/src/emu/luaengine.c
r31045r31046
1616#include "lua/lua.hpp"
1717#include "lua/lib/lualibs.h"
1818#include "web/mongoose.h"
19#include "lua/bridge/LuaBridge.h"
1920
2021//**************************************************************************
2122//  LUA ENGINE
r31045r31046
341342   return 1;
342343}
343344
344//-------------------------------------------------
345//  luaopen_emu - connect emu section lib
346//-------------------------------------------------
347
348int lua_engine::luaopen_emu(lua_State *L)
349{
350   static const struct luaL_Reg emu_funcs [] = {
351      { "gamename",    l_emu_gamename },
352      { "keypost",     l_emu_keypost },
353      { "hook_output", l_emu_hook_output },
354      { "time",        l_emu_time },
355      { "wait",        l_emu_wait },
356      { "after",       l_emu_after },
357      { "exit",       l_emu_exit },
358      { "start",        l_emu_start },
359      { NULL, NULL }  /* sentinel */
360   };
361
362   luaL_newlib(L, emu_funcs);
363   return 1;
364}
365
366345int lua_engine::luaopen_ioport(lua_State *L)
367346{
368347   static const struct luaL_Reg ioport_funcs [] = {
r31045r31046
466445   luaL_openlibs(m_lua_state);  /* open libraries */
467446   
468447   luaopen_lsqlite3(m_lua_state);
469   luaL_requiref(m_lua_state, "emu", luaopen_emu, 1);
470448   
471449   luaopen_ioport(m_lua_state);
472450
r31045r31046
515493
516494void lua_engine::initialize()
517495{
496   luabridge::getGlobalNamespace (m_lua_state)
497      .beginNamespace ("emu")
498         .addCFunction ("gamename",    l_emu_gamename )
499         .addCFunction ("keypost",     l_emu_keypost )
500         .addCFunction ("hook_output", l_emu_hook_output )
501         .addCFunction ("time",        l_emu_time )
502         .addCFunction ("wait",        l_emu_wait )
503         .addCFunction ("after",       l_emu_after )
504         .addCFunction ("exit",        l_emu_exit )
505         .addCFunction ("start",      l_emu_start )
506         .beginClass <machine_manager> ("manager")
507            .addFunction ("machine", &machine_manager::machine)
508            .addFunction ("options", &machine_manager::options)
509         .endClass ()
510         .beginClass <running_machine> ("machine")
511            .addFunction ("exit", &running_machine::schedule_exit)
512            .addFunction ("hard_reset", &running_machine::schedule_hard_reset)
513            .addFunction ("soft_reset", &running_machine::schedule_soft_reset)
514            .addFunction ("system", &running_machine::system)
515         .endClass ()
516         .beginClass <game_driver> ("game_driver")
517            .addData ("name", &game_driver::name)
518            .addData ("description", &game_driver::description)
519            .addData ("year", &game_driver::year)
520            .addData ("manufacturer", &game_driver::manufacturer)
521         .endClass ()
522      .endNamespace ();
523   luabridge::push (m_lua_state, machine_manager::instance());
524   lua_setglobal(m_lua_state, "manager");
525
518526   mg_start_thread(::serve_lua, this);
519527}
520528
trunk/src/emu/luaengine.h
r31045r31046
8686   void resume(void *L, INT32 param);
8787   void report_errors(int status);
8888   void start();
89   static int luaopen_emu(lua_State *L);
9089   static int luaopen_ioport(lua_State *L);
9190   void close();
9291
trunk/src/lib/lua/bridge/detail/TypeTraits.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6
7  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
8
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26*/
27//==============================================================================
28
29#ifndef LUABRIDGE_TYPEINFO_HEADER
30#define LUABRIDGE_TYPEINFO_HEADER
31
32//------------------------------------------------------------------------------
33/**
34    Container traits.
35
36    Unspecialized ContainerTraits has the isNotContainer typedef for SFINAE.
37    All user defined containers must supply an appropriate specialization for
38    ContinerTraits (without the typedef isNotContainer). The containers that
39    come with LuaBridge also come with the appropriate ContainerTraits
40    specialization. See the corresponding declaration for details.
41
42    A specialization of ContainerTraits for some generic type ContainerType
43    looks like this:
44
45        template <class T>
46        struct ContainerTraits <ContainerType <T> >
47        {
48          typedef typename T Type;
49
50          static T* get (ContainerType <T> const& c)
51          {
52            return c.get (); // Implementation-dependent on ContainerType
53          }
54        };
55*/
56template <class T>
57struct ContainerTraits
58{
59  typedef bool isNotContainer;
60};
61
62//------------------------------------------------------------------------------
63/**
64    Type traits.
65
66    Specializations return information about a type.
67*/
68struct TypeTraits
69{
70  /** Determine if type T is a container.
71
72      To be considered a container, there must be a specialization of
73      ContainerTraits with the required fields.
74  */
75  template <typename T>
76  class isContainer
77  {
78  private:
79    typedef char yes[1]; // sizeof (yes) == 1
80    typedef char no [2]; // sizeof (no)  == 2
81
82    template <typename C>
83    static no& test (typename C::isNotContainer*);
84 
85    template <typename>
86    static yes& test (...);
87 
88  public:
89    static const bool value = sizeof (test <ContainerTraits <T> >(0)) == sizeof (yes);
90  };
91
92  /** Determine if T is const qualified.
93  */
94  /** @{ */
95  template <class T>
96  struct isConst
97  {
98    static bool const value = false;
99  };
100
101  template <class T>
102  struct isConst <T const>
103  {
104    static bool const value = true;
105  };
106  /** @} */
107
108  /** Remove the const qualifier from T.
109  */
110  /** @{ */
111  template <class T>
112  struct removeConst
113  {
114    typedef T Type;
115  };
116
117  template <class T>
118  struct removeConst <T const>
119  {
120    typedef T Type;
121  };
122  /**@}*/
123};
124
125#endif
Property changes on: trunk/src/lib/lua/bridge/detail/TypeTraits.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/Userdata.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6
7  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
8
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26*/
27//==============================================================================
28
29//==============================================================================
30/**
31  Return the identity pointer for our lightuserdata tokens.
32
33  LuaBridge metatables are tagged with a security "token." The token is a
34  lightuserdata created from the identity pointer, used as a key in the
35  metatable. The value is a boolean = true, although any value could have been
36  used.
37
38  Because of Lua's dynamic typing and our improvised system of imposing C++
39  class structure, there is the possibility that executing scripts may
40  knowingly or unknowingly cause invalid data to get passed to the C functions
41  created by LuaBridge. In particular, our security model addresses the
42  following:
43
44  Notes:
45    1. Scripts cannot create a userdata (ignoring the debug lib).
46    2. Scripts cannot create a lightuserdata (ignoring the debug lib).
47    3. Scripts cannot set the metatable on a userdata.
48    4. Our identity key is a unique pointer in the process.
49    5. Our metatables have a lightuserdata identity key / value pair.
50    6. Our metatables have "__metatable" set to a boolean = false.
51    7. Our lightuserdata is unique.
52*/
53inline void* getIdentityKey ()
54{
55  static char value;
56  return &value;
57}
58
59/**
60  Interface to a class pointer retrievable from a userdata.
61*/
62class Userdata
63{
64protected:
65  void* m_p; // subclasses must set this
66
67  //--------------------------------------------------------------------------
68  /**
69    Get an untyped pointer to the contained class.
70  */
71  inline void* const getPointer ()
72  {
73    return m_p;
74  }
75
76private:
77  //--------------------------------------------------------------------------
78  /**
79    Validate and retrieve a Userdata on the stack.
80
81    The Userdata must exactly match the corresponding class table or
82    const table, or else a Lua error is raised. This is used for the
83    __gc metamethod.
84  */
85  static Userdata* getExactClass (lua_State* L,
86                                  int narg,
87                                  void const* classKey)
88  {
89    Userdata* ud = 0;
90    int const index = lua_absindex (L, narg);
91
92    bool mismatch = false;
93    char const* got = 0;
94
95    lua_rawgetp (L, LUA_REGISTRYINDEX, classKey);
96    assert (lua_istable (L, -1));
97
98    // Make sure we have a userdata.
99    if (!lua_isuserdata (L, index))
100      mismatch = true;
101
102    // Make sure it's metatable is ours.
103    if (!mismatch)
104    {
105      lua_getmetatable (L, index);
106      lua_rawgetp (L, -1, getIdentityKey ());
107      if (lua_isboolean (L, -1))
108      {
109        lua_pop (L, 1);
110      }
111      else
112      {
113        lua_pop (L, 2);
114        mismatch = true;
115      }     
116    }
117
118    if (!mismatch)
119    {
120      if (lua_rawequal (L, -1, -2))
121      {
122        // Matches class table.
123        lua_pop (L, 2);
124        ud = static_cast <Userdata*> (lua_touserdata (L, index));
125      }
126      else
127      {
128        rawgetfield (L, -2, "__const");
129        if (lua_rawequal (L, -1, -2))
130        {
131          // Matches const table
132          lua_pop (L, 3);
133          ud = static_cast <Userdata*> (lua_touserdata (L, index));
134        }
135        else
136        {
137          // Mismatch, but its one of ours so get a type name.
138          rawgetfield (L, -2, "__type");
139          lua_insert (L, -4);
140          lua_pop (L, 2);
141          got = lua_tostring (L, -2);
142          mismatch = true;
143        }
144      }
145    }
146
147    if (mismatch)
148    {
149      rawgetfield (L, -1, "__type");
150      assert (lua_type (L, -1) == LUA_TSTRING);
151      char const* const expected = lua_tostring (L, -1);
152
153      if (got == 0)
154        got = lua_typename (L, lua_type (L, index));
155
156      char const* const msg = lua_pushfstring (
157        L, "%s expected, got %s", expected, got);
158
159      if (narg > 0)
160        luaL_argerror (L, narg, msg);
161      else
162        lua_error (L);
163    }
164
165    return ud;
166  }
167
168  //--------------------------------------------------------------------------
169  /**
170    Validate and retrieve a Userdata on the stack.
171
172    The Userdata must be derived from or the same as the given base class,
173    identified by the key. If canBeConst is false, generates an error if
174    the resulting Userdata represents to a const object. We do the type check
175    first so that the error message is informative.
176  */
177  static Userdata* getClass (lua_State* L,
178                             int index,
179                             void const* baseClassKey,
180                             bool canBeConst)
181  {
182    assert (index > 0);
183    Userdata* ud = 0;
184
185    bool mismatch = false;
186    char const* got = 0;
187
188    lua_rawgetp (L, LUA_REGISTRYINDEX, baseClassKey);
189    assert (lua_istable (L, -1));
190
191    // Make sure we have a userdata.
192    if (lua_isuserdata (L, index))
193    {
194      // Make sure it's metatable is ours.
195      lua_getmetatable (L, index);
196      lua_rawgetp (L, -1, getIdentityKey ());
197      if (lua_isboolean (L, -1))
198      {
199        lua_pop (L, 1);
200
201        // If __const is present, object is NOT const.
202        rawgetfield (L, -1, "__const");
203        assert (lua_istable (L, -1) || lua_isnil (L, -1));
204        bool const isConst = lua_isnil (L, -1);
205        lua_pop (L, 1);
206
207        // Replace the class table with the const table if needed.
208        if (isConst)
209        {
210          rawgetfield (L, -2, "__const");
211          assert (lua_istable (L, -1));
212          lua_replace (L, -3);
213        }
214
215        for (;;)
216        {
217          if (lua_rawequal (L, -1, -2))
218          {
219            lua_pop (L, 2);
220
221            // Match, now check const-ness.
222            if (isConst && !canBeConst)
223            {
224              luaL_argerror (L, index, "cannot be const");
225            }
226            else
227            {
228              ud = static_cast <Userdata*> (lua_touserdata (L, index));
229              break;
230            }
231          }
232          else
233          {
234            // Replace current metatable with it's base class.
235            rawgetfield (L, -1, "__parent");
236/*
237ud
238class metatable
239ud metatable
240ud __parent (nil)
241*/
242
243            if (lua_isnil (L, -1))
244            {
245              lua_remove (L, -1);
246              // Mismatch, but its one of ours so get a type name.
247              rawgetfield (L, -1, "__type");
248              lua_insert (L, -3);
249              lua_pop (L, 1);
250              got = lua_tostring (L, -2);
251              mismatch = true;
252              break;
253            }
254            else
255            {
256              lua_remove (L, -2);
257            }
258          }
259        }
260      }
261      else
262      {
263        lua_pop (L, 2);
264        mismatch = true;
265      }     
266    }
267    else
268    {
269      mismatch = true;
270    }
271
272    if (mismatch)
273    {
274      assert (lua_type (L, -1) == LUA_TTABLE);
275      rawgetfield (L, -1, "__type");
276      assert (lua_type (L, -1) == LUA_TSTRING);
277      char const* const expected = lua_tostring (L, -1);
278
279      if (got == 0)
280        got = lua_typename (L, lua_type (L, index));
281
282      char const* const msg = lua_pushfstring (
283        L, "%s expected, got %s", expected, got);
284
285      luaL_argerror (L, index, msg);
286    }
287
288    return ud;
289  }
290
291public:
292  virtual ~Userdata () { }
293
294  //--------------------------------------------------------------------------
295  /**
296    Returns the Userdata* if the class on the Lua stack matches.
297
298    If the class does not match, a Lua error is raised.
299  */
300  template <class T>
301  static inline Userdata* getExact (lua_State* L, int index)
302  {
303    return getExactClass (L, index, ClassInfo <T>::getClassKey ());
304  }
305
306  //--------------------------------------------------------------------------
307  /**
308    Get a pointer to the class from the Lua stack.
309
310    If the object is not the class or a subclass, or it violates the
311    const-ness, a Lua error is raised.
312  */
313  template <class T>
314  static inline T* get (lua_State* L, int index, bool canBeConst)
315  {
316    if (lua_isnil (L, index))
317      return 0;
318    else
319      return static_cast <T*> (getClass (L, index,
320        ClassInfo <T>::getClassKey (), canBeConst)->getPointer ());
321  }
322};
323
324//----------------------------------------------------------------------------
325/**
326  Wraps a class object stored in a Lua userdata.
327
328  The lifetime of the object is managed by Lua. The object is constructed
329  inside the userdata using placement new.
330*/
331template <class T>
332class UserdataValue : public Userdata
333{
334private:
335  UserdataValue <T> (UserdataValue <T> const&);
336  UserdataValue <T> operator= (UserdataValue <T> const&);
337
338  char m_storage [sizeof (T)];
339
340  inline T* getObject ()
341  {
342    // If this fails to compile it means you forgot to provide
343    // a Container specialization for your container!
344    //
345    return reinterpret_cast <T*> (&m_storage [0]);
346  }
347
348private:
349  /**
350    Used for placement construction.
351  */
352  UserdataValue ()
353  {
354    m_p = getObject ();
355  }
356
357  ~UserdataValue ()
358  {
359    getObject ()->~T ();
360  }
361
362public:
363  /**
364    Push a T via placement new.
365
366    The caller is responsible for calling placement new using the
367    returned uninitialized storage.
368  */
369  static void* place (lua_State* const L)
370  {
371    UserdataValue <T>* const ud = new (
372      lua_newuserdata (L, sizeof (UserdataValue <T>))) UserdataValue <T> ();
373    lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
374    // If this goes off it means you forgot to register the class!
375    assert (lua_istable (L, -1));
376    lua_setmetatable (L, -2);
377    return ud->getPointer ();
378  }
379
380  /**
381    Push T via copy construction from U.
382  */
383  template <class U>
384  static inline void push (lua_State* const L, U const& u)
385  {
386    new (place (L)) U (u);
387  }
388};
389
390//----------------------------------------------------------------------------
391/**
392  Wraps a pointer to a class object inside a Lua userdata.
393
394  The lifetime of the object is managed by C++.
395*/
396class UserdataPtr : public Userdata
397{
398private:
399  UserdataPtr (UserdataPtr const&);
400  UserdataPtr operator= (UserdataPtr const&);
401
402private:
403  /** Push non-const pointer to object using metatable key.
404  */
405  static void push (lua_State* L, void* const p, void const* const key)
406  {
407    if (p)
408    {
409      new (lua_newuserdata (L, sizeof (UserdataPtr))) UserdataPtr (p);
410      lua_rawgetp (L, LUA_REGISTRYINDEX, key);
411      // If this goes off it means you forgot to register the class!
412      assert (lua_istable (L, -1));
413      lua_setmetatable (L, -2);
414    }
415    else
416    {
417      lua_pushnil (L);
418    }
419  }
420
421  /** Push const pointer to object using metatable key.
422  */
423  static void push (lua_State* L, void const* const p, void const* const key)
424  {
425    if (p)
426    {
427      new (lua_newuserdata (L, sizeof (UserdataPtr)))
428        UserdataPtr (const_cast <void*> (p));
429      lua_rawgetp (L, LUA_REGISTRYINDEX, key);
430      // If this goes off it means you forgot to register the class!
431      assert (lua_istable (L, -1));
432      lua_setmetatable (L, -2);
433    }
434    else
435    {
436      lua_pushnil (L);
437    }
438  }
439
440  explicit UserdataPtr (void* const p)
441  {
442    m_p = p;
443
444    // Can't construct with a null pointer!
445    //
446    assert (m_p != 0);
447  }
448
449public:
450  /** Push non-const pointer to object.
451  */
452  template <class T>
453  static inline void push (lua_State* const L, T* const p)
454  {
455    if (p)
456      push (L, p, ClassInfo <T>::getClassKey ());
457    else
458      lua_pushnil (L);
459  }
460
461  /** Push const pointer to object.
462  */
463  template <class T>
464  static inline void push (lua_State* const L, T const* const p)
465  {
466    if (p)
467      push (L, p, ClassInfo <T>::getConstKey ());
468    else
469      lua_pushnil (L);
470  }
471};
472
473//============================================================================
474/**
475  Wraps a container thet references a class object.
476
477  The template argument C is the container type, ContainerTraits must be
478  specialized on C or else a compile error will result.
479*/
480template <class C>
481class UserdataShared : public Userdata
482{
483private:
484  UserdataShared (UserdataShared <C> const&);
485  UserdataShared <C>& operator= (UserdataShared <C> const&);
486
487  typedef typename TypeTraits::removeConst <
488    typename ContainerTraits <C>::Type>::Type T;
489
490  C m_c;
491
492private:
493  ~UserdataShared ()
494  {
495  }
496
497public:
498  /**
499    Construct from a container to the class or a derived class.
500  */
501  template <class U>
502  explicit UserdataShared (U const& u) : m_c (u)
503  {
504    m_p = const_cast <void*> (reinterpret_cast <void const*> (
505        (ContainerTraits <C>::get (m_c))));
506  }
507
508  /**
509    Construct from a pointer to the class or a derived class.
510  */
511  template <class U>
512  explicit UserdataShared (U* u) : m_c (u)
513  {
514    m_p = const_cast <void*> (reinterpret_cast <void const*> (
515        (ContainerTraits <C>::get (m_c))));
516  }
517};
518
519//----------------------------------------------------------------------------
520//
521// SFINAE helpers.
522//
523
524// non-const objects
525template <class C, bool makeObjectConst>
526struct UserdataSharedHelper
527{
528  typedef typename TypeTraits::removeConst <
529    typename ContainerTraits <C>::Type>::Type T;
530
531  static void push (lua_State* L, C const& c)
532  {
533    if (ContainerTraits <C>::get (c) != 0)
534    {
535      new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c);
536      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
537      // If this goes off it means the class T is unregistered!
538      assert (lua_istable (L, -1));
539      lua_setmetatable (L, -2);
540    }
541    else
542    {
543      lua_pushnil (L);
544    }
545  }
546
547  static void push (lua_State* L, T* const t)
548  {
549    if (t)
550    {
551      new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t);
552      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
553      // If this goes off it means the class T is unregistered!
554      assert (lua_istable (L, -1));
555      lua_setmetatable (L, -2);
556    }
557    else
558    {
559      lua_pushnil (L);
560    }
561  }
562};
563
564// const objects
565template <class C>
566struct UserdataSharedHelper <C, true>
567{
568  typedef typename TypeTraits::removeConst <
569    typename ContainerTraits <C>::Type>::Type T;
570
571  static void push (lua_State* L, C const& c)
572  {
573    if (ContainerTraits <C>::get (c) != 0)
574    {
575      new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c);
576      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
577      // If this goes off it means the class T is unregistered!
578      assert (lua_istable (L, -1));
579      lua_setmetatable (L, -2);
580    }
581    else
582    {
583      lua_pushnil (L);
584    }
585  }
586
587  static void push (lua_State* L, T* const t)
588  {
589    if (t)
590    {
591      new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t);
592      lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
593      // If this goes off it means the class T is unregistered!
594      assert (lua_istable (L, -1));
595      lua_setmetatable (L, -2);
596    }
597    else
598    {
599      lua_pushnil (L);
600    }
601  }
602};
603
604/**
605  Pass by container.
606
607  The container controls the object lifetime. Typically this will be a
608  lifetime shared by C++ and Lua using a reference count. Because of type
609  erasure, containers like std::shared_ptr will not work. Containers must
610  either be of the intrusive variety, or in the style of the RefCountedPtr
611  type provided by LuaBridge (that uses a global hash table).
612*/
613template <class C, bool byContainer>
614struct StackHelper
615{
616  static inline void push (lua_State* L, C const& c)
617  {
618    UserdataSharedHelper <C,
619      TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, c);
620  }
621
622  typedef typename TypeTraits::removeConst <
623    typename ContainerTraits <C>::Type>::Type T;
624
625  static inline C get (lua_State* L, int index)
626  {
627    return Userdata::get <T> (L, index, true);
628  }
629};
630
631/**
632  Pass by value.
633
634  Lifetime is managed by Lua. A C++ function which accesses a pointer or
635  reference to an object outside the activation record in which it was
636  retrieved may result in undefined behavior if Lua garbage collected it.
637*/
638template <class T>
639struct StackHelper <T, false>
640{
641  static inline void push (lua_State* L, T const& t)
642  {
643    UserdataValue <T>::push (L, t);
644  }
645
646  static inline T const& get (lua_State* L, int index)
647  {
648    return *Userdata::get <T> (L, index, true);
649  }
650};
651
652//==============================================================================
653
654/**
655  Lua stack conversions for class objects passed by value.
656*/
657template <class T>
658struct Stack
659{
660public:
661  static inline void push (lua_State* L, T const& t)
662  {
663    StackHelper <T,
664      TypeTraits::isContainer <T>::value>::push (L, t);
665  }
666
667  static inline T get (lua_State* L, int index)
668  {
669    return StackHelper <T,
670      TypeTraits::isContainer <T>::value>::get (L, index);
671  }
672};
673
674//------------------------------------------------------------------------------
675/**
676  Lua stack conversions for pointers and references to class objects.
677
678  Lifetime is managed by C++. Lua code which remembers a reference to the
679  value may result in undefined behavior if C++ destroys the object. The
680  handling of the const and volatile qualifiers happens in UserdataPtr.
681*/
682
683// pointer
684template <class T>
685struct Stack <T*>
686{
687  static inline void push (lua_State* L, T* const p)
688  {
689    UserdataPtr::push (L, p);
690  }
691
692  static inline T* const get (lua_State* L, int index)
693  {
694    return Userdata::get <T> (L, index, false);
695  }
696};
697
698// Strips the const off the right side of *
699template <class T>
700struct Stack <T* const>
701{
702  static inline void push (lua_State* L, T* const p)
703  {
704    UserdataPtr::push (L, p);
705  }
706
707  static inline T* const get (lua_State* L, int index)
708  {
709    return Userdata::get <T> (L, index, false);
710  }
711};
712
713// pointer to const
714template <class T>
715struct Stack <T const*>
716{
717  static inline void push (lua_State* L, T const* const p)
718  {
719    UserdataPtr::push (L, p);
720  }
721
722  static inline T const* const get (lua_State* L, int index)
723  {
724    return Userdata::get <T> (L, index, true);
725  }
726};
727
728// Strips the const off the right side of *
729template <class T>
730struct Stack <T const* const>
731{
732  static inline void push (lua_State* L, T const* const p)
733  {
734    UserdataPtr::push (L, p);
735  }
736
737  static inline T const* const get (lua_State* L, int index)
738  {
739    return Userdata::get <T> (L, index, true);
740  }
741};
742
743// reference
744template <class T>
745struct Stack <T&>
746{
747  static inline void push (lua_State* L, T& t)
748  {
749    UserdataPtr::push (L, &t);
750  }
751
752  static T& get (lua_State* L, int index)
753  {
754    T* const t = Userdata::get <T> (L, index, false);
755    if (!t)
756      luaL_error (L, "nil passed to reference");
757    return *t;
758  }
759};
760
761template <class C, bool byContainer>
762struct RefStackHelper
763{
764  typedef C return_type; 
765   
766  static inline void push (lua_State* L, C const& t)
767  {
768    UserdataSharedHelper <C,
769      TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, t);
770  }
771
772  typedef typename TypeTraits::removeConst <
773    typename ContainerTraits <C>::Type>::Type T;
774
775  static return_type get (lua_State* L, int index)
776  {
777    return Userdata::get <T> (L, index, true);
778  }
779};
780
781template <class T>
782struct RefStackHelper <T, false>
783{
784  typedef T const& return_type; 
785   
786   static inline void push (lua_State* L, T const& t)
787   {
788     UserdataPtr::push (L, &t);
789   }
790
791  static return_type get (lua_State* L, int index)
792  {
793    T const* const t = Userdata::get <T> (L, index, true);
794
795    if (!t)
796      luaL_error (L, "nil passed to reference");
797    return *t;
798  }
799   
800};
801
802// reference to const
803template <class T>
804struct Stack <T const&>
805{
806  typedef RefStackHelper <T, TypeTraits::isContainer <T>::value> helper_t;
807 
808  static inline void push (lua_State* L, T const& t)
809  {
810    helper_t::push (L, t);
811  }
812
813  static typename helper_t::return_type get (lua_State* L, int index)
814  {
815    return helper_t::get (L, index);
816  }
817};
Property changes on: trunk/src/lib/lua/bridge/detail/Userdata.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/Iterator.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6
7  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
8
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26*/
27//==============================================================================
28
29/** Allows table iteration.
30*/
31class Iterator
32{
33private:
34  lua_State* m_L;
35  LuaRef m_table;
36  LuaRef m_key;
37  LuaRef m_value;
38
39  void next ()
40  {
41    m_table.push(m_L);
42    m_key.push (m_L);
43    if (lua_next (m_L, -2))
44    {
45      m_value.pop (m_L);
46      m_key.pop (m_L);
47    }
48    else
49    {
50      m_key = Nil();
51      m_value = Nil();
52    }
53    lua_pop(m_L, 1);
54  }
55
56public:
57  explicit Iterator (LuaRef table)
58    : m_L (table.state ())
59    , m_table (table)
60    , m_key (table.state ()) // m_key is nil
61    , m_value (table.state ()) // m_value is nil
62  {
63    next (); // get the first (key, value) pair from table
64  }
65
66  lua_State* state () const
67  {
68    return m_L;
69  }
70
71  LuaRef operator* () const
72  {
73    return m_value;
74  }
75
76  LuaRef operator-> () const
77  {
78    return m_value;
79  }
80
81  Iterator& operator++ ()
82  {
83    if (isNil())
84    {
85      // if the iterator reaches the end, do nothing
86      return *this;
87    }
88    else
89    {
90      next();
91      return *this;
92    }
93  }
94
95  inline bool isNil () const
96  {
97    return m_key.isNil ();
98  }
99
100  inline LuaRef key () const
101  {
102    return m_key;
103  }
104
105  inline LuaRef value () const
106  {
107    return m_value;
108  }
109
110private:
111  // Don't use postfix increment, it is less efficient
112  Iterator operator++ (int);
113};
114
Property changes on: trunk/src/lib/lua/bridge/detail/Iterator.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/CFunctions.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6
7  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
8
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26*/
27//==============================================================================
28
29// We use a structure so we can define everything in the header.
30//
31struct CFunc
32{
33  //----------------------------------------------------------------------------
34  /**
35      __index metamethod for a namespace or class static members.
36
37      This handles:
38        Retrieving functions and class static methods, stored in the metatable.
39        Reading global and class static data, stored in the __propget table.
40        Reading global and class properties, stored in the __propget table.
41  */
42  static int indexMetaMethod (lua_State* L)
43  {
44    int result = 0;
45    lua_getmetatable (L, 1);                // push metatable of arg1
46    for (;;)
47    {
48      lua_pushvalue (L, 2);                 // push key arg2
49      lua_rawget (L, -2);                   // lookup key in metatable
50      if (lua_isnil (L, -1))                // not found
51      {
52        lua_pop (L, 1);                     // discard nil
53        rawgetfield (L, -1, "__propget");   // lookup __propget in metatable
54        lua_pushvalue (L, 2);               // push key arg2
55        lua_rawget (L, -2);                 // lookup key in __propget
56        lua_remove (L, -2);                 // discard __propget
57        if (lua_iscfunction (L, -1))
58        {
59          lua_remove (L, -2);               // discard metatable
60          lua_pushvalue (L, 1);             // push arg1
61          lua_call (L, 1, 1);               // call cfunction
62          result = 1;
63          break;
64        }
65        else
66        {
67          assert (lua_isnil (L, -1));
68          lua_pop (L, 1);                   // discard nil and fall through
69        }
70      }
71      else
72      {
73        assert (lua_istable (L, -1) || lua_iscfunction (L, -1));
74        lua_remove (L, -2);
75        result = 1;
76        break;
77      }
78
79      rawgetfield (L, -1, "__parent");
80      if (lua_istable (L, -1))
81      {
82        // Remove metatable and repeat the search in __parent.
83        lua_remove (L, -2);
84      }
85      else
86      {
87        // Discard metatable and return nil.
88        assert (lua_isnil (L, -1));
89        lua_remove (L, -2);
90        result = 1;
91        break;
92      }
93    }
94
95    return result;
96  }
97
98  //----------------------------------------------------------------------------
99  /**
100      __newindex metamethod for a namespace or class static members.
101
102      The __propset table stores proxy functions for assignment to:
103        Global and class static data.
104        Global and class properties.
105  */
106  static int newindexMetaMethod (lua_State* L)
107  {
108    int result = 0;
109    lua_getmetatable (L, 1);                // push metatable of arg1
110    for (;;)
111    {
112      rawgetfield (L, -1, "__propset");     // lookup __propset in metatable
113      assert (lua_istable (L, -1));
114      lua_pushvalue (L, 2);                 // push key arg2
115      lua_rawget (L, -2);                   // lookup key in __propset
116      lua_remove (L, -2);                   // discard __propset
117      if (lua_iscfunction (L, -1))          // ensure value is a cfunction
118      {
119        lua_remove (L, -2);                 // discard metatable
120        lua_pushvalue (L, 3);               // push new value arg3
121        lua_call (L, 1, 0);                 // call cfunction
122        result = 0;
123        break;
124      }
125      else
126      {
127        assert (lua_isnil (L, -1));
128        lua_pop (L, 1);
129      }
130
131      rawgetfield (L, -1, "__parent");
132      if (lua_istable (L, -1))
133      {
134        // Remove metatable and repeat the search in __parent.
135        lua_remove (L, -2);
136      }
137      else
138      {
139        assert (lua_isnil (L, -1));
140        lua_pop (L, 2);
141        result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2));
142      }
143    }
144
145    return result;
146  }
147
148  //----------------------------------------------------------------------------
149  /**
150      lua_CFunction to report an error writing to a read-only value.
151
152      The name of the variable is in the first upvalue.
153  */
154  static int readOnlyError (lua_State* L)
155  {
156    std::string s;
157   
158    s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only";
159
160    return luaL_error (L, s.c_str ());
161  }
162 
163  //----------------------------------------------------------------------------
164  /**
165      lua_CFunction to get a variable.
166
167      This is used for global variables or class static data members.
168
169      The pointer to the data is in the first upvalue.
170  */
171  template <class T>
172  static int getVariable (lua_State* L)
173  {
174    assert (lua_islightuserdata (L, lua_upvalueindex (1)));
175    T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1)));
176    assert (ptr != 0);
177    Stack <T>::push (L, *ptr);
178    return 1;
179  }
180
181  //----------------------------------------------------------------------------
182  /**
183      lua_CFunction to set a variable.
184
185      This is used for global variables or class static data members.
186
187      The pointer to the data is in the first upvalue.
188  */
189  template <class T>
190  static int setVariable (lua_State* L)
191  {
192    assert (lua_islightuserdata (L, lua_upvalueindex (1)));
193    T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1)));
194    assert (ptr != 0);
195    *ptr = Stack <T>::get (L, 1);
196    return 0;
197  }
198
199  //----------------------------------------------------------------------------
200  /**
201      lua_CFunction to call a function with a return value.
202
203      This is used for global functions, global properties, class static methods,
204      and class static properties.
205
206      The function pointer is in the first upvalue.
207  */
208  template <class FnPtr,
209            class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
210  struct Call
211  {
212    typedef typename FuncTraits <FnPtr>::Params Params;
213    static int f (lua_State* L)
214    {
215      assert (isfulluserdata (L, lua_upvalueindex (1)));
216      FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
217      assert (fnptr != 0);
218      ArgList <Params> args (L);
219      Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args));
220      return 1;
221    }
222  };
223
224  //----------------------------------------------------------------------------
225  /**
226      lua_CFunction to call a function with no return value.
227
228      This is used for global functions, global properties, class static methods,
229      and class static properties.
230
231      The function pointer is in the first upvalue.
232  */
233  template <class FnPtr>
234  struct Call <FnPtr, void>
235  {
236    typedef typename FuncTraits <FnPtr>::Params Params;
237    static int f (lua_State* L)
238    {
239      assert (isfulluserdata (L, lua_upvalueindex (1)));
240      FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
241      assert (fnptr != 0);
242      ArgList <Params> args (L);
243      FuncTraits <FnPtr>::call (fnptr, args);
244      return 0;
245    }
246  };
247
248  //----------------------------------------------------------------------------
249  /**
250      lua_CFunction to call a class member function with a return value.
251
252      The member function pointer is in the first upvalue.
253      The class userdata object is at the top of the Lua stack.
254  */
255  template <class MemFnPtr,
256            class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
257  struct CallMember
258  {
259    typedef typename FuncTraits <MemFnPtr>::ClassType T;
260    typedef typename FuncTraits <MemFnPtr>::Params Params;
261
262    static int f (lua_State* L)
263    {
264      assert (isfulluserdata (L, lua_upvalueindex (1)));
265      T* const t = Userdata::get <T> (L, 1, false);
266      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
267      assert (fnptr != 0);
268      ArgList <Params, 2> args (L);
269      Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
270      return 1;
271    }
272  };
273
274  template <class MemFnPtr,
275            class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
276  struct CallConstMember
277  {
278    typedef typename FuncTraits <MemFnPtr>::ClassType T;
279    typedef typename FuncTraits <MemFnPtr>::Params Params;
280
281    static int f (lua_State* L)
282    {
283      assert (isfulluserdata (L, lua_upvalueindex (1)));
284      T const* const t = Userdata::get <T> (L, 1, true);
285      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
286      assert (fnptr != 0);
287      ArgList <Params, 2> args(L);
288      Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
289      return 1;
290    }
291  };
292
293  //----------------------------------------------------------------------------
294  /**
295      lua_CFunction to call a class member function with no return value.
296
297      The member function pointer is in the first upvalue.
298      The class userdata object is at the top of the Lua stack.
299  */
300  template <class MemFnPtr>
301  struct CallMember <MemFnPtr, void>
302  {
303    typedef typename FuncTraits <MemFnPtr>::ClassType T;
304    typedef typename FuncTraits <MemFnPtr>::Params Params;
305
306    static int f (lua_State* L)
307    {
308      assert (isfulluserdata (L, lua_upvalueindex (1)));
309      T* const t = Userdata::get <T> (L, 1, false);
310      MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
311      assert (fnptr != 0);
312      ArgList <Params, 2> args (L);
313      FuncTraits <MemFnPtr>::call (t, fnptr, args);
314      return 0;
315    }
316  };
317
318  template <class MemFnPtr>
319  struct CallConstMember <MemFnPtr, void>
320  {
321    typedef typename FuncTraits <MemFnPtr>::ClassType T;
322    typedef typename FuncTraits <MemFnPtr>::Params Params;
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);
331      FuncTraits <MemFnPtr>::call (t, fnptr, args);
332      return 0;
333    }
334  };
335
336  //--------------------------------------------------------------------------
337  /**
338      lua_CFunction to call a class member lua_CFunction.
339
340      The member function pointer is in the first upvalue.
341      The class userdata object is at the top of the Lua stack.
342  */
343  template <class T>
344  struct CallMemberCFunction
345  {
346    static int f (lua_State* L)
347    {
348      assert (isfulluserdata (L, lua_upvalueindex (1)));
349      typedef int (T::*MFP)(lua_State* L);
350      T* const t = Userdata::get <T> (L, 1, false);
351      MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
352      assert (fnptr != 0);
353      return (t->*fnptr) (L);
354    }
355  };
356
357  template <class T>
358  struct CallConstMemberCFunction
359  {
360    static int f (lua_State* L)
361    {
362      assert (isfulluserdata (L, lua_upvalueindex (1)));
363      typedef int (T::*MFP)(lua_State* L);
364      T const* const t = Userdata::get <T> (L, 1, true);
365      MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
366      assert (fnptr != 0);
367      return (t->*fnptr) (L);
368    }
369  };
370
371  //--------------------------------------------------------------------------
372
373  // SFINAE Helpers
374
375  template <class MemFnPtr, bool isConst>
376  struct CallMemberFunctionHelper
377  {
378    static void add (lua_State* L, char const* name, MemFnPtr mf)
379    {
380      new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
381      lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1);
382      lua_pushvalue (L, -1);
383      rawsetfield (L, -5, name); // const table
384      rawsetfield (L, -3, name); // class table
385    }
386  };
387
388  template <class MemFnPtr>
389  struct CallMemberFunctionHelper <MemFnPtr, false>
390  {
391    static void add (lua_State* L, char const* name, MemFnPtr mf)
392    {
393      new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
394      lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1);
395      rawsetfield (L, -3, name); // class table
396    }
397  };
398
399  //--------------------------------------------------------------------------
400  /**
401      __gc metamethod for a class.
402  */
403  template <class C>
404  static int gcMetaMethod (lua_State* L)
405  {
406    Userdata* const ud = Userdata::getExact <C> (L, 1);
407    ud->~Userdata ();
408    return 0;
409  }
410
411  //--------------------------------------------------------------------------
412  /**
413      lua_CFunction to get a class data member.
414
415      The pointer-to-member is in the first upvalue.
416      The class userdata object is at the top of the Lua stack.
417  */
418  template <class C, typename T>
419  static int getProperty (lua_State* L)
420  {
421    C const* const c = Userdata::get <C> (L, 1, true);
422    T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
423    Stack <T>::push (L, c->**mp);
424    return 1;
425  }
426
427  //--------------------------------------------------------------------------
428  /**
429      lua_CFunction to set a class data member.
430
431      The pointer-to-member is in the first upvalue.
432      The class userdata object is at the top of the Lua stack.
433  */
434  template <class C, typename T>
435  static int setProperty (lua_State* L)
436  {
437    C* const c = Userdata::get <C> (L, 1, false);
438    T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
439    c->**mp = Stack <T>::get (L, 2);
440    return 0;
441  }
442};
Property changes on: trunk/src/lib/lua/bridge/detail/CFunctions.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/Namespace.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2007, Nathan Reed
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/** Provides C++ to Lua registration capabilities.
31
32    This class is not instantiated directly, call `getGlobalNamespace` to start
33    the registration process.
34*/
35class Namespace
36{
37private:
38  Namespace& operator= (Namespace const& other);
39
40  lua_State* const L;
41  int mutable m_stackSize;
42
43private:
44  //============================================================================
45  /**
46    Error reporting.
47
48    VF: This function looks handy, why aren't we using it?
49  */
50#if 0
51  static int luaError (lua_State* L, std::string message)
52  {
53    assert (lua_isstring (L, lua_upvalueindex (1)));
54    std::string s;
55
56    // Get information on the caller's caller to format the message,
57    // so the error appears to originate from the Lua source.
58    lua_Debug ar;
59    int result = lua_getstack (L, 2, &ar);
60    if (result != 0)
61    {
62      lua_getinfo (L, "Sl", &ar);
63      s = ar.short_src;
64      if (ar.currentline != -1)
65      {
66        // poor mans int to string to avoid <strstrream>.
67        lua_pushnumber (L, ar.currentline);
68        s = s + ":" + lua_tostring (L, -1) + ": ";
69        lua_pop (L, 1);
70      }
71    }
72
73    s = s + message;
74
75    return luaL_error (L, s.c_str ());
76  }
77#endif
78
79  //----------------------------------------------------------------------------
80  /**
81    Pop the Lua stack.
82  */
83  void pop (int n) const
84  {
85    if (m_stackSize >= n && lua_gettop (L) >= n)
86    {
87      lua_pop (L, n);
88      m_stackSize -= n;
89    }
90    else
91    {
92      throw std::logic_error ("invalid stack");
93    }
94  }
95
96private:
97  /**
98    Factored base to reduce template instantiations.
99  */
100  class ClassBase
101  {
102  private:
103    ClassBase& operator= (ClassBase const& other);
104
105  protected:
106    friend class Namespace;
107
108    lua_State* const L;
109    int mutable m_stackSize;
110
111  protected:
112    //--------------------------------------------------------------------------
113    /**
114      __index metamethod for a class.
115
116      This implements member functions, data members, and property members.
117      Functions are stored in the metatable and const metatable. Data members
118      and property members are in the __propget table.
119
120      If the key is not found, the search proceeds up the hierarchy of base
121      classes.
122    */
123    static int indexMetaMethod (lua_State* L)
124    {
125      int result = 0;
126
127      assert (lua_isuserdata (L, 1));               // warn on security bypass
128      lua_getmetatable (L, 1);                      // get metatable for object
129      for (;;)
130      {
131        lua_pushvalue (L, 2);                       // push key arg2
132        lua_rawget (L, -2);                         // lookup key in metatable
133        if (lua_iscfunction (L, -1))                // ensure its a cfunction
134        {
135          lua_remove (L, -2);                       // remove metatable
136          result = 1;
137          break;
138        }
139        else if (lua_isnil (L, -1))
140        {
141          lua_pop (L, 1);
142        }
143        else
144        {
145          lua_pop (L, 2);
146          throw std::logic_error ("not a cfunction");
147        }
148
149        rawgetfield (L, -1, "__propget");           // get __propget table
150        if (lua_istable (L, -1))                    // ensure it is a table
151        {
152          lua_pushvalue (L, 2);                     // push key arg2
153          lua_rawget (L, -2);                       // lookup key in __propget
154          lua_remove (L, -2);                       // remove __propget
155          if (lua_iscfunction (L, -1))              // ensure its a cfunction
156          {
157            lua_remove (L, -2);                     // remove metatable
158            lua_pushvalue (L, 1);                   // push class arg1
159            lua_call (L, 1, 1);
160            result = 1;
161            break;
162          }
163          else if (lua_isnil (L, -1))
164          {
165            lua_pop (L, 1);
166          }
167          else
168          {
169            lua_pop (L, 2);
170
171            // We only put cfunctions into __propget.
172            throw std::logic_error ("not a cfunction");
173          }
174        }
175        else
176        {
177          lua_pop (L, 2);
178
179          // __propget is missing, or not a table.
180          throw std::logic_error ("missing __propget table");
181        }
182
183        // Repeat the lookup in the __parent metafield,
184        // or return nil if the field doesn't exist.
185        rawgetfield (L, -1, "__parent");
186        if (lua_istable (L, -1))
187        {
188          // Remove metatable and repeat the search in __parent.
189          lua_remove (L, -2);
190        }
191        else if (lua_isnil (L, -1))
192        {
193          result = 1;
194          break;
195        }
196        else
197        {
198          lua_pop (L, 2);
199
200          throw std::logic_error ("__parent is not a table");
201        }
202      }
203
204      return result;
205    }
206
207    //--------------------------------------------------------------------------
208    /**
209      __newindex metamethod for classes.
210
211      This supports writable variables and properties on class objects. The
212      corresponding object is passed in the first parameter to the set function.
213    */
214    static int newindexMetaMethod (lua_State* L)
215    {
216      int result = 0;
217
218      lua_getmetatable (L, 1);
219
220      for (;;)
221      {
222        // Check __propset
223        rawgetfield (L, -1, "__propset");
224        if (!lua_isnil (L, -1))
225        {
226          lua_pushvalue (L, 2);
227          lua_rawget (L, -2);
228          if (!lua_isnil (L, -1))
229          {
230            // found it, call the setFunction.
231            assert (lua_isfunction (L, -1));
232            lua_pushvalue (L, 1);
233            lua_pushvalue (L, 3);
234            lua_call (L, 2, 0);
235            result = 0;
236            break;
237          }
238          lua_pop (L, 1);
239        }
240        lua_pop (L, 1);
241
242        // Repeat the lookup in the __parent metafield.
243        rawgetfield (L, -1, "__parent");
244        if (lua_isnil (L, -1))
245        {
246          // Either the property or __parent must exist.
247          result = luaL_error (L,
248            "no member named '%s'", lua_tostring (L, 2));
249        }
250        lua_remove (L, -2);
251      }
252
253      return result;
254    }
255
256    //--------------------------------------------------------------------------
257    /**
258      Create the const table.
259    */
260    void createConstTable (char const* name)
261    {
262      lua_newtable (L);
263      lua_pushvalue (L, -1);
264      lua_setmetatable (L, -2);
265      lua_pushboolean (L, 1);
266      lua_rawsetp (L, -2, getIdentityKey ());
267      lua_pushstring (L, (std::string ("const ") + name).c_str ());
268      rawsetfield (L, -2, "__type");
269      lua_pushcfunction (L, &indexMetaMethod);
270      rawsetfield (L, -2, "__index");
271      lua_pushcfunction (L, &newindexMetaMethod);
272      rawsetfield (L, -2, "__newindex");
273      lua_newtable (L);
274      rawsetfield (L, -2, "__propget");
275     
276      if (Security::hideMetatables ())
277      {
278        lua_pushnil (L);
279        rawsetfield (L, -2, "__metatable");
280      }
281    }
282
283    //--------------------------------------------------------------------------
284    /**
285      Create the class table.
286
287      The Lua stack should have the const table on top.
288    */
289    void createClassTable (char const* name)
290    {
291      lua_newtable (L);
292      lua_pushvalue (L, -1);
293      lua_setmetatable (L, -2);
294      lua_pushboolean (L, 1);
295      lua_rawsetp (L, -2, getIdentityKey ());
296      lua_pushstring (L, name);
297      rawsetfield (L, -2, "__type");
298      lua_pushcfunction (L, &indexMetaMethod);
299      rawsetfield (L, -2, "__index");
300      lua_pushcfunction (L, &newindexMetaMethod);
301      rawsetfield (L, -2, "__newindex");
302      lua_newtable (L);
303      rawsetfield (L, -2, "__propget");
304      lua_newtable (L);
305      rawsetfield (L, -2, "__propset");
306
307      lua_pushvalue (L, -2);
308      rawsetfield (L, -2, "__const"); // point to const table
309
310      lua_pushvalue (L, -1);
311      rawsetfield (L, -3, "__class"); // point const table to class table
312
313      if (Security::hideMetatables ())
314      {
315        lua_pushnil (L);
316        rawsetfield (L, -2, "__metatable");
317      }
318    }
319
320    //--------------------------------------------------------------------------
321    /**
322      Create the static table.
323
324      The Lua stack should have:
325        -1 class table
326        -2 const table
327        -3 enclosing namespace
328    */
329    void createStaticTable (char const* name)
330    {
331      lua_newtable (L);
332      lua_newtable (L);
333      lua_pushvalue (L, -1);
334      lua_setmetatable (L, -3);
335      lua_insert (L, -2);
336      rawsetfield (L, -5, name);
337
338#if 0
339      lua_pushlightuserdata (L, this);
340      lua_pushcclosure (L, &tostringMetaMethod, 1);
341      rawsetfield (L, -2, "__tostring");
342#endif
343      lua_pushcfunction (L, &CFunc::indexMetaMethod);
344      rawsetfield (L, -2, "__index");
345      lua_pushcfunction (L, &CFunc::newindexMetaMethod);
346      rawsetfield (L, -2, "__newindex");
347      lua_newtable (L);
348      rawsetfield (L, -2, "__propget");
349      lua_newtable (L);
350      rawsetfield (L, -2, "__propset");
351
352      lua_pushvalue (L, -2);
353      rawsetfield (L, -2, "__class"); // point to class table
354
355      if (Security::hideMetatables ())
356      {
357        lua_pushnil (L);
358        rawsetfield (L, -2, "__metatable");
359      }
360    }
361
362    //==========================================================================
363    /**
364      lua_CFunction to construct a class object wrapped in a container.
365    */
366    template <class Params, class C>
367    static int ctorContainerProxy (lua_State* L)
368    {
369      typedef typename ContainerTraits <C>::Type T;
370      ArgList <Params, 2> args (L);
371      T* const p = Constructor <T, Params>::call (args);
372      UserdataSharedHelper <C, false>::push (L, p);
373      return 1;
374    }
375
376    //--------------------------------------------------------------------------
377    /**
378      lua_CFunction to construct a class object in-place in the userdata.
379    */
380    template <class Params, class T>
381    static int ctorPlacementProxy (lua_State* L)
382    {
383      ArgList <Params, 2> args (L);
384      Constructor <T, Params>::call (UserdataValue <T>::place (L), args);
385      return 1;
386    }
387
388    //--------------------------------------------------------------------------
389    /**
390      Pop the Lua stack.
391    */
392    void pop (int n) const
393    {
394      if (m_stackSize >= n && lua_gettop (L) >= n)
395      {
396        lua_pop (L, n);
397        m_stackSize -= n;
398      }
399      else
400      {
401        throw std::logic_error ("invalid stack");
402      }
403    }
404
405  public:
406    //--------------------------------------------------------------------------
407    explicit ClassBase (lua_State* L_)
408      : L (L_)
409      , m_stackSize (0)
410    {
411    }
412
413    //--------------------------------------------------------------------------
414    /**
415      Copy Constructor.
416    */
417    ClassBase (ClassBase const& other)
418      : L (other.L)
419      , m_stackSize (0)
420    {
421      m_stackSize = other.m_stackSize;
422      other.m_stackSize = 0;
423    }
424
425    ~ClassBase ()
426    {
427      pop (m_stackSize);
428    }
429  };
430
431  //============================================================================
432  //
433  // Class
434  //
435  //============================================================================
436  /**
437    Provides a class registration in a lua_State.
438
439    After contstruction the Lua stack holds these objects:
440      -1 static table
441      -2 class table
442      -3 const table
443      -4 (enclosing namespace)
444  */
445  template <class T>
446  class Class : public ClassBase
447  {
448  public:
449    //==========================================================================
450    /**
451      Register a new class or add to an existing class registration.
452    */
453    Class (char const* name, Namespace const* parent) : ClassBase (parent->L)
454    {
455      m_stackSize = parent->m_stackSize + 3;
456      parent->m_stackSize = 0;
457
458      assert (lua_istable (L, -1));
459      rawgetfield (L, -1, name);
460     
461      if (lua_isnil (L, -1))
462      {
463        lua_pop (L, 1);
464
465        createConstTable (name);
466        lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
467        rawsetfield (L, -2, "__gc");
468
469        createClassTable (name);
470        lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
471        rawsetfield (L, -2, "__gc");
472
473        createStaticTable (name);
474
475        // Map T back to its tables.
476        lua_pushvalue (L, -1);
477        lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
478        lua_pushvalue (L, -2);
479        lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
480        lua_pushvalue (L, -3);
481        lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
482      }
483      else
484      {
485        rawgetfield (L, -1, "__class");
486        rawgetfield (L, -1, "__const");
487
488        // Reverse the top 3 stack elements
489        lua_insert (L, -3);
490        lua_insert (L, -2);
491      }
492    }
493
494    //==========================================================================
495    /**
496      Derive a new class.
497    */
498    Class (char const* name, Namespace const* parent, void const* const staticKey)
499      : ClassBase (parent->L)
500    {
501      m_stackSize = parent->m_stackSize + 3;
502      parent->m_stackSize = 0;
503
504      assert (lua_istable (L, -1));
505
506      createConstTable (name);
507      lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
508      rawsetfield (L, -2, "__gc");
509
510      createClassTable (name);
511      lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
512      rawsetfield (L, -2, "__gc");
513
514      createStaticTable (name);
515
516      lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey);
517      assert (lua_istable (L, -1));
518      rawgetfield (L, -1, "__class");
519      assert (lua_istable (L, -1));
520      rawgetfield (L, -1, "__const");
521      assert (lua_istable (L, -1));
522
523      rawsetfield (L, -6, "__parent");
524      rawsetfield (L, -4, "__parent");
525      rawsetfield (L, -2, "__parent");
526
527      lua_pushvalue (L, -1);
528      lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
529      lua_pushvalue (L, -2);
530      lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
531      lua_pushvalue (L, -3);
532      lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
533    }
534
535    //--------------------------------------------------------------------------
536    /**
537      Continue registration in the enclosing namespace.
538    */
539    Namespace endClass ()
540    {
541      return Namespace (this);
542    }
543
544    //--------------------------------------------------------------------------
545    /**
546      Add or replace a static data member.
547    */
548    template <class U>
549    Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
550    {
551      assert (lua_istable (L, -1));
552
553      rawgetfield (L, -1, "__propget");
554      assert (lua_istable (L, -1));
555      lua_pushlightuserdata (L, pu);
556      lua_pushcclosure (L, &CFunc::getVariable <U>, 1);
557      rawsetfield (L, -2, name);
558      lua_pop (L, 1);
559
560      rawgetfield (L, -1, "__propset");
561      assert (lua_istable (L, -1));
562      if (isWritable)
563      {
564        lua_pushlightuserdata (L, pu);
565        lua_pushcclosure (L, &CFunc::setVariable <U>, 1);
566      }
567      else
568      {
569        lua_pushstring (L, name);
570        lua_pushcclosure (L, &CFunc::readOnlyError, 1);
571      }
572      rawsetfield (L, -2, name);
573      lua_pop (L, 1);
574
575      return *this;
576    }
577
578    //--------------------------------------------------------------------------
579    /**
580      Add or replace a static property member.
581
582      If the set function is null, the property is read-only.
583    */
584    template <class U>
585    Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0)
586    {
587      typedef U (*get_t)();
588      typedef void (*set_t)(U);
589     
590      assert (lua_istable (L, -1));
591
592      rawgetfield (L, -1, "__propget");
593      assert (lua_istable (L, -1));
594      new (lua_newuserdata (L, sizeof (get))) get_t (get);
595      lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1);
596      rawsetfield (L, -2, name);
597      lua_pop (L, 1);
598
599      rawgetfield (L, -1, "__propset");
600      assert (lua_istable (L, -1));
601      if (set != 0)
602      {
603        new (lua_newuserdata (L, sizeof (set))) set_t (set);
604        lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1);
605      }
606      else
607      {
608        lua_pushstring (L, name);
609        lua_pushcclosure (L, &CFunc::readOnlyError, 1);
610      }
611      rawsetfield (L, -2, name);
612      lua_pop (L, 1);
613
614      return *this;
615    }
616
617    //--------------------------------------------------------------------------
618    /**
619      Add or replace a static member function.
620    */
621    template <class FP>
622    Class <T>& addStaticFunction (char const* name, FP const fp)
623    {
624      new (lua_newuserdata (L, sizeof (fp))) FP (fp);
625      lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
626      rawsetfield (L, -2, name);
627
628      return *this;
629    }
630
631    //--------------------------------------------------------------------------
632    /**
633      Add or replace a lua_CFunction.
634    */
635    Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*))
636    {
637      lua_pushcfunction (L, fp);
638      rawsetfield (L, -2, name);
639      return *this;
640    }
641
642    //--------------------------------------------------------------------------
643    /**
644      Add or replace a data member.
645    */
646    template <class U>
647    Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
648    {
649      typedef const U T::*mp_t;
650
651      // Add to __propget in class and const tables.
652      {
653        rawgetfield (L, -2, "__propget");
654        rawgetfield (L, -4, "__propget");
655        new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
656        lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1);
657        lua_pushvalue (L, -1);
658        rawsetfield (L, -4, name);
659        rawsetfield (L, -2, name);
660        lua_pop (L, 2);
661      }
662
663      if (isWritable)
664      {
665        // Add to __propset in class table.
666        rawgetfield (L, -2, "__propset");
667        assert (lua_istable (L, -1));
668        new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
669        lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1);
670        rawsetfield (L, -2, name);
671        lua_pop (L, 1);
672      }
673
674      return *this;
675    }
676
677    //--------------------------------------------------------------------------
678    /**
679      Add or replace a property member.
680    */
681    template <class TG, class TS>
682    Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS))
683    {
684      // Add to __propget in class and const tables.
685      {
686        rawgetfield (L, -2, "__propget");
687        rawgetfield (L, -4, "__propget");
688        typedef TG (T::*get_t) () const;
689        new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
690        lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
691        lua_pushvalue (L, -1);
692        rawsetfield (L, -4, name);
693        rawsetfield (L, -2, name);
694        lua_pop (L, 2);
695      }
696
697      {
698        // Add to __propset in class table.
699        rawgetfield (L, -2, "__propset");
700        assert (lua_istable (L, -1));
701        typedef void (T::* set_t) (TS);
702        new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
703        lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1);
704        rawsetfield (L, -2, name);
705        lua_pop (L, 1);
706      }
707
708      return *this;
709    }
710
711    // read-only
712    template <class TG>
713    Class <T>& addProperty (char const* name, TG (T::* get) () const)
714    {
715      // Add to __propget in class and const tables.
716      rawgetfield (L, -2, "__propget");
717      rawgetfield (L, -4, "__propget");
718      typedef TG (T::*get_t) () const;
719      new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
720      lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
721      lua_pushvalue (L, -1);
722      rawsetfield (L, -4, name);
723      rawsetfield (L, -2, name);
724      lua_pop (L, 2);
725
726      return *this;
727    }
728
729    //--------------------------------------------------------------------------
730    /**
731      Add or replace a property member, by proxy.
732
733      When a class is closed for modification and does not provide (or cannot
734      provide) the function signatures necessary to implement get or set for
735      a property, this will allow non-member functions act as proxies.
736
737      Both the get and the set functions require a T const* and T* in the first
738      argument respectively.
739    */
740    template <class TG, class TS>
741    Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS))
742    {
743      // Add to __propget in class and const tables.
744      {
745        rawgetfield (L, -2, "__propget");
746        rawgetfield (L, -4, "__propget");
747        typedef TG (*get_t) (T const*);
748        new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
749        lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
750        lua_pushvalue (L, -1);
751        rawsetfield (L, -4, name);
752        rawsetfield (L, -2, name);
753        lua_pop (L, 2);
754      }
755
756      if (set != 0)
757      {
758        // Add to __propset in class table.
759        rawgetfield (L, -2, "__propset");
760        assert (lua_istable (L, -1));
761        typedef void (*set_t) (T*, TS);
762        new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
763        lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1);
764        rawsetfield (L, -2, name);
765        lua_pop (L, 1);
766      }
767
768      return *this;
769    }
770
771    // read-only
772    template <class TG, class TS>
773    Class <T>& addProperty (char const* name, TG (*get) (T const*))
774    {
775      // Add to __propget in class and const tables.
776      rawgetfield (L, -2, "__propget");
777      rawgetfield (L, -4, "__propget");
778      typedef TG (*get_t) (T const*);
779      new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
780      lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
781      lua_pushvalue (L, -1);
782      rawsetfield (L, -4, name);
783      rawsetfield (L, -2, name);
784      lua_pop (L, 2);
785
786      return *this;
787    }
788
789    //--------------------------------------------------------------------------
790    /**
791        Add or replace a member function.
792    */
793    template <class MemFn>
794    Class <T>& addFunction (char const* name, MemFn mf)
795    {
796      CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
797      return *this;
798    }
799
800    //--------------------------------------------------------------------------
801    /**
802        Add or replace a member lua_CFunction.
803    */
804    Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*))
805    {
806      typedef int (T::*MFP)(lua_State*);
807      assert (lua_istable (L, -1));
808      new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
809      lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1);
810      rawsetfield (L, -3, name); // class table
811
812      return *this;
813    }
814
815    //--------------------------------------------------------------------------
816    /**
817        Add or replace a const member lua_CFunction.
818    */
819    Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
820    {
821      typedef int (T::*MFP)(lua_State*) const;
822      assert (lua_istable (L, -1));
823      new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
824      lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
825      lua_pushvalue (L, -1);
826      rawsetfield (L, -5, name); // const table
827      rawsetfield (L, -3, name); // class table
828
829      return *this;
830    }
831
832    //--------------------------------------------------------------------------
833    /**
834      Add or replace a primary Constructor.
835
836      The primary Constructor is invoked when calling the class type table
837      like a function.
838
839      The template parameter should be a function pointer type that matches
840      the desired Constructor (since you can't take the address of a Constructor
841      and pass it as an argument).
842    */
843    template <class MemFn, class C>
844    Class <T>& addConstructor ()
845    {
846      lua_pushcclosure (L,
847        &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
848      rawsetfield(L, -2, "__call");
849
850      return *this;
851    }
852
853    template <class MemFn>
854    Class <T>& addConstructor ()
855    {
856      lua_pushcclosure (L,
857        &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
858      rawsetfield(L, -2, "__call");
859
860      return *this;
861    }
862  };
863
864private:
865  //----------------------------------------------------------------------------
866  /**
867      Open the global namespace for registrations.
868  */
869  explicit Namespace (lua_State* L_)
870    : L (L_)
871    , m_stackSize (0)
872  {
873    lua_getglobal (L, "_G");
874    ++m_stackSize;
875  }
876
877  //----------------------------------------------------------------------------
878  /**
879      Open a namespace for registrations.
880
881      The namespace is created if it doesn't already exist.
882      The parent namespace is at the top of the Lua stack.
883  */
884  Namespace (char const* name, Namespace const* parent)
885    : L (parent->L)
886    , m_stackSize (0)
887  {
888    m_stackSize = parent->m_stackSize + 1;
889    parent->m_stackSize = 0;
890
891    assert (lua_istable (L, -1));
892    rawgetfield (L, -1, name);
893    if (lua_isnil (L, -1))
894    {
895      lua_pop (L, 1);
896
897      lua_newtable (L);
898      lua_pushvalue (L, -1);
899      lua_setmetatable (L, -2);
900      lua_pushcfunction (L, &CFunc::indexMetaMethod);
901      rawsetfield (L, -2, "__index");
902      lua_pushcfunction (L, &CFunc::newindexMetaMethod);
903      rawsetfield (L, -2, "__newindex");
904      lua_newtable (L);
905      rawsetfield (L, -2, "__propget");
906      lua_newtable (L);
907      rawsetfield (L, -2, "__propset");
908      lua_pushvalue (L, -1);
909      rawsetfield (L, -3, name);
910#if 0
911      lua_pushcfunction (L, &tostringMetaMethod);
912      rawsetfield (L, -2, "__tostring");
913#endif
914    }
915  }
916
917  //----------------------------------------------------------------------------
918  /**
919      Creates a continued registration from a child namespace.
920  */
921  explicit Namespace (Namespace const* child)
922    : L (child->L)
923    , m_stackSize (0)
924  {
925    m_stackSize = child->m_stackSize - 1;
926    child->m_stackSize = 1;
927    child->pop (1);
928
929    // It is not necessary or valid to call
930    // endNamespace() for the global namespace!
931    //
932    assert (m_stackSize != 0);
933  }
934
935  //----------------------------------------------------------------------------
936  /**
937      Creates a continued registration from a child class.
938  */
939  explicit Namespace (ClassBase const* child)
940    : L (child->L)
941    , m_stackSize (0)
942  {
943    m_stackSize = child->m_stackSize - 3;
944    child->m_stackSize = 3;
945    child->pop (3);
946  }
947
948public:
949  //----------------------------------------------------------------------------
950  /**
951      Copy Constructor.
952
953      Ownership of the stack is transferred to the new object. This happens
954      when the compiler emits temporaries to hold these objects while chaining
955      registrations across namespaces.
956  */
957  Namespace (Namespace const& other) : L (other.L)
958  {
959    m_stackSize = other.m_stackSize;
960    other.m_stackSize = 0;
961  }
962
963  //----------------------------------------------------------------------------
964  /**
965      Closes this namespace registration.
966  */
967  ~Namespace ()
968  {
969    pop (m_stackSize);
970  }
971
972  //----------------------------------------------------------------------------
973  /**
974      Open the global namespace.
975  */
976  static Namespace getGlobalNamespace (lua_State* L)
977  {
978    return Namespace (L);
979  }
980
981  //----------------------------------------------------------------------------
982  /**
983      Open a new or existing namespace for registrations.
984  */
985  Namespace beginNamespace (char const* name)
986  {
987    return Namespace (name, this);
988  }
989
990  //----------------------------------------------------------------------------
991  /**
992      Continue namespace registration in the parent.
993
994      Do not use this on the global namespace.
995  */
996  Namespace endNamespace ()
997  {
998    return Namespace (this);
999  }
1000
1001  //----------------------------------------------------------------------------
1002  /**
1003      Add or replace a variable.
1004  */
1005  template <class T>
1006  Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
1007  {
1008    assert (lua_istable (L, -1));
1009
1010    rawgetfield (L, -1, "__propget");
1011    assert (lua_istable (L, -1));
1012    lua_pushlightuserdata (L, pt);
1013    lua_pushcclosure (L, &CFunc::getVariable <T>, 1);
1014    rawsetfield (L, -2, name);
1015    lua_pop (L, 1);
1016
1017    rawgetfield (L, -1, "__propset");
1018    assert (lua_istable (L, -1));
1019    if (isWritable)
1020    {
1021      lua_pushlightuserdata (L, pt);
1022      lua_pushcclosure (L, &CFunc::setVariable <T>, 1);
1023    }
1024    else
1025    {
1026      lua_pushstring (L, name);
1027      lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1028    }
1029    rawsetfield (L, -2, name);
1030    lua_pop (L, 1);
1031
1032    return *this;
1033  }
1034 
1035  //----------------------------------------------------------------------------
1036  /**
1037      Add or replace a property.
1038
1039      If the set function is omitted or null, the property is read-only.
1040  */
1041  template <class TG, class TS>
1042  Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0)
1043  {
1044    assert (lua_istable (L, -1));
1045
1046    rawgetfield (L, -1, "__propget");
1047    assert (lua_istable (L, -1));
1048    typedef TG (*get_t) ();
1049    new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
1050    lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1);
1051    rawsetfield (L, -2, name);
1052    lua_pop (L, 1);
1053
1054    rawgetfield (L, -1, "__propset");
1055    assert (lua_istable (L, -1));
1056    if (set != 0)
1057    {
1058      typedef void (*set_t) (TS);
1059      new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
1060      lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
1061    }
1062    else
1063    {
1064      lua_pushstring (L, name);
1065      lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1066    }
1067    rawsetfield (L, -2, name);
1068    lua_pop (L, 1);
1069
1070    return *this;
1071  }
1072
1073  //----------------------------------------------------------------------------
1074  /**
1075      Add or replace a free function.
1076  */
1077  template <class FP>
1078  Namespace& addFunction (char const* name, FP const fp)
1079  {
1080    assert (lua_istable (L, -1));
1081
1082    new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1083    lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
1084    rawsetfield (L, -2, name);
1085
1086    return *this;
1087  }
1088
1089  //----------------------------------------------------------------------------
1090  /**
1091      Add or replace a lua_CFunction.
1092  */
1093  Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
1094  {
1095    lua_pushcfunction (L, fp);
1096    rawsetfield (L, -2, name);
1097
1098    return *this;
1099  }
1100
1101  //----------------------------------------------------------------------------
1102  /**
1103      Open a new or existing class for registrations.
1104  */
1105  template <class T>
1106  Class <T> beginClass (char const* name)
1107  {
1108    return Class <T> (name, this);
1109  }
1110
1111  //----------------------------------------------------------------------------
1112  /**
1113      Derive a new class for registrations.
1114
1115      To continue registrations for the class later, use beginClass().
1116      Do not call deriveClass() again.
1117  */
1118  template <class T, class U>
1119  Class <T> deriveClass (char const* name)
1120  {
1121    return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
1122  }
1123};
1124
1125//------------------------------------------------------------------------------
1126/**
1127    Retrieve the global namespace.
1128
1129    It is recommended to put your namespace inside the global namespace, and
1130    then add your classes and functions to it, rather than adding many classes
1131    and functions directly to the global namespace.
1132*/
1133inline Namespace getGlobalNamespace (lua_State* L)
1134{
1135  return Namespace::getGlobalNamespace (L);
1136}
Property changes on: trunk/src/lib/lua/bridge/detail/Namespace.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/TypeList.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2007, Nathan Reed
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  This file incorporates work covered by the following copyright and
29  permission notice: 
30
31    The Loki Library
32    Copyright (c) 2001 by Andrei Alexandrescu
33    This code accompanies the book:
34    Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
35        Patterns Applied". Copyright (c) 2001. Addison-Wesley.
36    Permission to use, copy, modify, distribute and sell this software for any
37        purpose is hereby granted without fee, provided that the above copyright
38        notice appear in all copies and that both that copyright notice and this
39        permission notice appear in supporting documentation.
40    The author or Addison-Welsey Longman make no representations about the
41        suitability of this software for any purpose. It is provided "as is"
42        without express or implied warranty.
43*/
44//==============================================================================
45
46/**
47  None type means void parameters or return value.
48*/
49typedef void None;
50
51template <typename Head, typename Tail = None>
52struct TypeList
53{
54};
55
56/**
57  A TypeList with actual values.
58*/
59template <typename List>
60struct TypeListValues
61{
62  static std::string const tostring (bool)
63  {
64    return "";
65  }
66};
67
68/**
69  TypeListValues recursive template definition.
70*/
71template <typename Head, typename Tail>
72struct TypeListValues <TypeList <Head, Tail> >
73{
74  Head hd;
75  TypeListValues <Tail> tl;
76
77  TypeListValues (Head hd_, TypeListValues <Tail> const& tl_)
78    : hd (hd_), tl (tl_)
79  {
80  }
81
82  static std::string const tostring (bool comma = false)
83  {
84    std::string s;
85
86    if (comma)
87      s = ", ";
88
89    s = s + typeid (Head).name ();
90
91    return s + TypeListValues <Tail>::tostring (true);
92  }
93};
94
95// Specializations of type/value list for head types that are references and
96// const-references.  We need to handle these specially since we can't count
97// on the referenced object hanging around for the lifetime of the list.
98
99template <typename Head, typename Tail>
100struct TypeListValues <TypeList <Head&, Tail> >
101{
102  Head hd;
103  TypeListValues <Tail> tl;
104
105  TypeListValues (Head& hd_, TypeListValues <Tail> const& tl_)
106    : hd (hd_), tl (tl_)
107  {
108  }
109
110  static std::string const tostring (bool comma = false)
111  {
112    std::string s;
113
114    if (comma)
115      s = ", ";
116
117    s = s + typeid (Head).name () + "&";
118
119    return s + TypeListValues <Tail>::tostring (true);
120  }
121};
122
123template <typename Head, typename Tail>
124struct TypeListValues <TypeList <Head const&, Tail> >
125{
126  Head hd;
127  TypeListValues <Tail> tl;
128
129  TypeListValues (Head const& hd_, const TypeListValues <Tail>& tl_)
130    : hd (hd_), tl (tl_)
131  {
132  }
133
134  static std::string const tostring (bool comma = false)
135  {
136    std::string s;
137
138    if (comma)
139      s = ", ";
140
141    s = s + typeid (Head).name () + " const&";
142
143    return s + TypeListValues <Tail>::tostring (true);
144  }
145};
146
147//==============================================================================
148/**
149  Subclass of a TypeListValues constructable from the Lua stack.
150*/
151
152template <typename List, int Start = 1>
153struct ArgList
154{
155};
156
157template <int Start>
158struct ArgList <None, Start> : public TypeListValues <None>
159{
160  ArgList (lua_State*)
161  {
162  }
163};
164
165template <typename Head, typename Tail, int Start>
166struct ArgList <TypeList <Head, Tail>, Start>
167  : public TypeListValues <TypeList <Head, Tail> >
168{
169  ArgList (lua_State* L)
170    : TypeListValues <TypeList <Head, Tail> > (Stack <Head>::get (L, Start),
171                                            ArgList <Tail, Start + 1> (L))
172  {
173  }
174};
Property changes on: trunk/src/lib/lua/bridge/detail/TypeList.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/LuaRef.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@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//------------------------------------------------------------------------------
31/**
32    Type tag for representing LUA_TNIL.
33
34    Construct one of these using `Nil()` to represent a Lua nil. This is faster
35    than creating a reference in the registry to nil. Example:
36
37        LuaRef t (LuaRef::createTable (L));
38        ...
39        t ["k"] = Nil(); // assign nil
40*/
41struct Nil
42{
43};
44
45//------------------------------------------------------------------------------
46/**
47    Lightweight reference to a Lua object.
48
49    The reference is maintained for the lifetime of the C++ object.
50*/
51class LuaRef
52{
53private:
54  class Proxy;
55  friend struct Stack <Proxy>;
56
57  //----------------------------------------------------------------------------
58  /**
59      Pop the Lua stack.
60
61      Pops the specified number of stack items on destruction. We use this
62      when returning objects, to avoid an explicit temporary variable, since
63      the destructor executes after the return statement. For example:
64
65          template <class U>
66          U cast (lua_State* L)
67          {
68            StackPop p (L, 1);
69            ...
70            return U (); // dtor called after this line
71          }
72
73      @note The `StackPop` object must always be a named local variable.
74  */
75  class StackPop
76  {
77  public:
78    /** Create a StackPop object.
79
80        @param count The number of stack entries to pop on destruction.
81    */
82    StackPop (lua_State* L, int count)
83      : m_L (L)
84      , m_count (count)
85    {
86    }
87
88    ~StackPop ()
89    {
90      lua_pop (m_L, m_count);
91    }
92
93  private:
94    lua_State* m_L;
95    int m_count;
96  };
97
98  //----------------------------------------------------------------------------
99  /**
100      A proxy for representing table values.
101  */
102  class Proxy
103  {
104  private:
105    lua_State* m_L;
106    int m_tableRef;
107    int m_keyRef;
108
109  public:
110    //--------------------------------------------------------------------------
111    /**
112        Construct a Proxy from a table value.
113
114        The table is in the registry, and the key is at the top of the stack.
115        The key is popped off the stack.
116    */
117    Proxy (lua_State* L, int tableRef)
118      : m_L (L)
119      , m_tableRef (tableRef)
120      , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX))
121    {
122    }
123
124    //--------------------------------------------------------------------------
125    /**
126        Create a Proxy via copy constructor.
127
128        It is best to avoid code paths that invoke this, because it creates
129        an extra temporary Lua reference. Typically this is done by passing
130        the Proxy parameter as a `const` reference.
131    */
132    Proxy (Proxy const& other)
133      : m_L (other.m_L)
134      , m_tableRef (other.m_tableRef)
135    {
136      // If this assert goes off it means code is taking this path,
137      // which is better avoided.
138      //
139      assert (0);
140
141      lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef);
142      m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX);
143    }
144
145    //--------------------------------------------------------------------------
146    /**
147        Destroy the proxy.
148
149        This does not destroy the table value.
150    */
151    ~Proxy ()
152    {
153      luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef);
154    }
155
156    //--------------------------------------------------------------------------
157    /**
158        Return a reference to the table value.
159    */
160    int createRef () const
161    {
162      push (m_L);
163      return luaL_ref (m_L, LUA_REGISTRYINDEX);
164    }
165
166    //--------------------------------------------------------------------------
167    /**
168        Assign a new value to this table key.
169
170        This may invoke metamethods.
171    */
172    template <class T>
173    Proxy& operator= (T v)
174    {
175      StackPop p (m_L, 1);
176      lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
177      lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
178      Stack <T>::push (m_L, v);
179      lua_rawset (m_L, -3);
180      return *this;
181    }
182
183    //--------------------------------------------------------------------------
184    /**
185        Assign a new value to this table key.
186
187        The assignment is raw, no metamethods are invoked.
188    */
189    template <class T>
190    Proxy& rawset (T v)
191    {
192      StackPop p (m_L, 1);
193      lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
194      lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
195      Stack <T>::push (m_L, v);
196      lua_settable (m_L, -3);
197      return *this;
198    }
199
200    //==========================================================================
201    //
202    // This group of member functions mirrors the member functions in LuaRef.
203
204    /** Retrieve the lua_State associated with the table value.
205    */
206    lua_State* state () const
207    {
208      return m_L;
209    }
210
211    //--------------------------------------------------------------------------
212    /**
213        Push the value onto the Lua stack.
214    */
215    void push (lua_State* L) const
216    {
217      assert (equalstates (L, m_L));
218      lua_rawgeti (L, LUA_REGISTRYINDEX, m_tableRef);
219      lua_rawgeti (L, LUA_REGISTRYINDEX, m_keyRef);
220      lua_gettable (L, -2);
221      lua_remove (L, -2); // remove the table
222    }
223
224    //--------------------------------------------------------------------------
225    /**
226        Determine the object type.
227
228        The return values are the same as for `lua_type`.
229    */
230    int type () const
231    {
232      int result;
233      push (m_L);
234      result = lua_type (m_L, -1);
235      lua_pop (m_L, 1);
236      return result;
237    }
238
239    inline bool isNil () const { return type () == LUA_TNIL; }
240    inline bool isNumber () const { return type () == LUA_TNUMBER; }
241    inline bool isString () const { return type () == LUA_TSTRING; }
242    inline bool isTable () const { return type () == LUA_TTABLE; }
243    inline bool isFunction () const { return type () == LUA_TFUNCTION; }
244    inline bool isUserdata () const { return type () == LUA_TUSERDATA; }
245    inline bool isThread () const { return type () == LUA_TTHREAD; }
246    inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
247
248    //--------------------------------------------------------------------------
249    /**
250        Perform an explicit conversion.
251    */
252    template <class T>
253    T cast () const
254    {
255      StackPop p (m_L, 1);
256      push (m_L);
257
258      // lua_gettop is used because Userdata::getClass() doesn't handle
259      // negative stack indexes.
260      //
261      return Stack <T>::get (m_L, lua_gettop (m_L));
262    }
263
264    //--------------------------------------------------------------------------
265    /**
266        Universal implicit conversion operator.
267
268        NOTE: Visual Studio 2010 and 2012 have a bug where this function
269              is not used. See:
270
271        http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
272        https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
273
274            // This code snippet fails to compile in vs2010,vs2012
275            struct S {
276              template <class T> inline operator T () const { return T (); }
277            };
278            int main () {
279              S () || false;
280              return 0;
281            }
282    */
283    template <class T>
284    inline operator T () const
285    {
286      return cast <T> ();
287    }
288
289    //--------------------------------------------------------------------------
290    /**
291        Universal comparison operators.
292    */
293    /** @{ */
294    template <class T>
295    bool operator== (T rhs) const
296    {
297      StackPop p (m_L, 2);
298      push (m_L);
299      Stack <T>::push (m_L, rhs);
300      return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
301    }
302
303    template <class T>
304    bool operator< (T rhs) const
305    {
306      StackPop p (m_L, 2);
307      push (m_L);
308      Stack <T>::push (m_L, rhs);
309      return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
310    }
311
312    template <class T>
313    bool operator<= (T rhs) const
314    {
315      StackPop p (m_L, 2);
316      push (m_L);
317      Stack <T>::push (m_L, rhs);
318      return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
319    }
320
321    template <class T>
322    bool operator> (T rhs) const
323    {
324      StackPop p (m_L, 2);
325      push (m_L);
326      Stack <T>::push (m_L, rhs);
327      return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
328    }
329
330    template <class T>
331    bool operator>= (T rhs) const
332    {
333      StackPop p (m_L, 2);
334      push (m_L);
335      Stack <T>::push (m_L, rhs);
336      return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
337    }
338
339    template <class T>
340    bool rawequal (T rhs) const
341    {
342      StackPop p (m_L, 2);
343      push (m_L);
344      Stack <T>::push (m_L, rhs);
345      return lua_rawequal (m_L, -1, -2) == 1;
346    }
347    /** @} */
348
349    //--------------------------------------------------------------------------
350    /**
351        Access a table value using a key.
352
353        This invokes metamethods.
354    */
355    template <class T>
356    Proxy operator[] (T key) const
357    {
358      return LuaRef (*this) [key];
359    }
360
361    //--------------------------------------------------------------------------
362    /**
363        Access a table value using a key.
364
365        The operation is raw, metamethods are not invoked. The result is
366        passed by value and may not be modified.
367    */
368    template <class T>
369    LuaRef rawget (T key) const
370    {
371      StackPop (m_L, 1);
372      push (m_L);
373      Stack <T>::push (m_L, key);
374      lua_rawget (m_L, -2);
375      return LuaRef (m_L, FromStack ());
376    }
377
378    //--------------------------------------------------------------------------
379    /**
380        Append a value to the table.
381
382        If the table is a sequence this will add another element to it.
383    */
384    template <class T>
385    void append (T v) const
386    {
387      push (m_L);
388      Stack <T>::push (m_L, v);
389      luaL_ref (m_L, -2);
390      lua_pop (m_L, 1);
391    }
392
393    //--------------------------------------------------------------------------
394    /**
395        Call the length operator.
396
397        This is identical to applying the Lua # operator.
398    */
399    int length () const
400    {
401      StackPop p (m_L, 1);
402      push (m_L);
403      return get_length (m_L, -1);
404    }
405
406    //--------------------------------------------------------------------------
407    /**
408        Call Lua code.
409
410        These overloads allow Lua code to be called with up to 8 parameters.
411        The return value is provided as a LuaRef (which may be LUA_REFNIL).
412        If an error occurs, a LuaException is thrown.
413    */
414    /** @{ */
415    LuaRef const operator() () const
416    {
417      push (m_L);
418      LuaException::pcall (m_L, 0, 1);
419      return LuaRef (m_L, FromStack ());
420    }
421
422    template <class P1>
423    LuaRef const operator() (P1 p1) const
424    {
425      push (m_L);
426      Stack <P1>::push (m_L, p1);
427      LuaException::pcall (m_L, 1, 1);
428      return LuaRef (m_L, FromStack ());
429    }
430
431    template <class P1, class P2>
432    LuaRef const operator() (P1 p1, P2 p2) const
433    {
434      push (m_L);
435      Stack <P1>::push (m_L, p1);
436      Stack <P2>::push (m_L, p2);
437      LuaException::pcall (m_L, 2, 1);
438      return LuaRef (m_L, FromStack ());
439    }
440
441    template <class P1, class P2, class P3>
442    LuaRef const operator() (P1 p1, P2 p2, P3 p3) const
443    {
444      push (m_L);
445      Stack <P1>::push (m_L, p1);
446      Stack <P2>::push (m_L, p2);
447      Stack <P3>::push (m_L, p3);
448      LuaException::pcall (m_L, 3, 1);
449      return LuaRef (m_L, FromStack ());
450    }
451
452    template <class P1, class P2, class P3, class P4>
453    LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
454    {
455      push (m_L);
456      Stack <P1>::push (m_L, p1);
457      Stack <P2>::push (m_L, p2);
458      Stack <P3>::push (m_L, p3);
459      Stack <P4>::push (m_L, p4);
460      LuaException::pcall (m_L, 4, 1);
461      return LuaRef (m_L, FromStack ());
462    }
463
464    template <class P1, class P2, class P3, class P4, class P5>
465    LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
466    {
467      push (m_L);
468      Stack <P1>::push (m_L, p1);
469      Stack <P2>::push (m_L, p2);
470      Stack <P3>::push (m_L, p3);
471      Stack <P4>::push (m_L, p4);
472      Stack <P5>::push (m_L, p5);
473      LuaException::pcall (m_L, 5, 1);
474      return LuaRef (m_L, FromStack ());
475    }
476
477    template <class P1, class P2, class P3, class P4, class P5, class P6>
478    LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
479    {
480      push (m_L);
481      Stack <P1>::push (m_L, p1);
482      Stack <P2>::push (m_L, p2);
483      Stack <P3>::push (m_L, p3);
484      Stack <P4>::push (m_L, p4);
485      Stack <P5>::push (m_L, p5);
486      Stack <P6>::push (m_L, p6);
487      LuaException::pcall (m_L, 6, 1);
488      return LuaRef (m_L, FromStack ());
489    }
490
491    template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
492    LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
493    {
494      push (m_L);
495      Stack <P1>::push (m_L, p1);
496      Stack <P2>::push (m_L, p2);
497      Stack <P3>::push (m_L, p3);
498      Stack <P4>::push (m_L, p4);
499      Stack <P5>::push (m_L, p5);
500      Stack <P6>::push (m_L, p6);
501      Stack <P7>::push (m_L, p7);
502      LuaException::pcall (m_L, 7, 1);
503      return LuaRef (m_L, FromStack ());
504    }
505
506    template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
507    LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
508    {
509      push (m_L);
510      Stack <P1>::push (m_L, p1);
511      Stack <P2>::push (m_L, p2);
512      Stack <P3>::push (m_L, p3);
513      Stack <P4>::push (m_L, p4);
514      Stack <P5>::push (m_L, p5);
515      Stack <P6>::push (m_L, p6);
516      Stack <P7>::push (m_L, p7);
517      Stack <P8>::push (m_L, p8);
518      LuaException::pcall (m_L, 8, 1);
519      return LuaRef (m_L, FromStack ());
520    }
521    /** @} */
522
523    //==========================================================================
524  };
525
526private:
527  friend struct Stack <LuaRef>;
528
529  //----------------------------------------------------------------------------
530  /**
531      Type tag for stack construction.
532  */
533  struct FromStack { };
534
535  //----------------------------------------------------------------------------
536  /**
537      Create a reference to an object at the top of the Lua stack and pop it.
538
539      This constructor is private and not invoked directly.
540      Instead, use the `fromStack` function.
541
542      @note The object is popped.
543  */
544  LuaRef (lua_State* L, FromStack)
545    : m_L (L)
546  {
547    m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
548  }
549
550  //----------------------------------------------------------------------------
551  /**
552      Create a reference to an object on the Lua stack.
553
554      This constructor is private and not invoked directly.
555      Instead, use the `fromStack` function.
556
557      @note The object is not popped.
558  */
559  LuaRef (lua_State* L, int index, FromStack)
560    : m_L (L)
561  {
562    lua_pushvalue (m_L, index);
563    m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
564  }
565
566  //----------------------------------------------------------------------------
567
568  // This type of construction is disallowed, since we don't have a `lua_State`.
569  //
570  template <class T>
571  LuaRef (T)
572  {
573  }
574
575  //----------------------------------------------------------------------------
576  /**
577      Create a reference to this ref.
578
579      This is used internally.
580  */
581  int createRef () const
582  {
583    if (m_ref != LUA_REFNIL)
584    {
585      push (m_L);
586      return luaL_ref (m_L, LUA_REGISTRYINDEX);
587    }
588    else
589    {
590      return LUA_REFNIL;
591    }
592  }
593
594public:
595  //----------------------------------------------------------------------------
596  /**
597      Create a nil reference.
598
599      The LuaRef may be assigned later.
600  */
601  LuaRef (lua_State* L)
602    : m_L (L)
603    , m_ref (LUA_REFNIL)
604  {
605  }
606
607  //----------------------------------------------------------------------------
608  /**
609      Create a reference to a value.
610  */
611  template <class T>
612  LuaRef (lua_State* L, T v)
613    : m_L (L)
614  {
615    Stack <T>::push (m_L, v);
616    m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
617  }
618
619  //----------------------------------------------------------------------------
620  /**
621      Create a reference to a table value.
622  */
623  LuaRef (Proxy const& v)
624    : m_L (v.state ())
625    , m_ref (v.createRef ())
626  {
627  }
628
629  //----------------------------------------------------------------------------
630  /**
631      Create a new reference to an existing reference.
632  */
633  LuaRef (LuaRef const& other)
634    : m_L (other.m_L)
635    , m_ref (other.createRef ())
636  {
637  }
638
639  //----------------------------------------------------------------------------
640  /**
641      Destroy a reference.
642
643      The corresponding Lua registry reference will be released.
644
645      @note If the state refers to a thread, it is the responsibility of the
646            caller to ensure that the thread still exists when the LuaRef
647            is destroyed.
648  */
649  ~LuaRef ()
650  {
651    luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
652  }
653
654  //----------------------------------------------------------------------------
655  /**
656      Return a LuaRef from a stack item.
657
658      The stack item is not popped.
659  */
660  static LuaRef fromStack (lua_State* L, int index)
661  {
662    lua_pushvalue (L, index);
663    return LuaRef (L, FromStack ());
664  }
665
666  //----------------------------------------------------------------------------
667  /**
668      Create a new empty table and return a reference to it.
669
670      It is also possible to use the free function `newTable`.
671
672      @see ::getGlobal
673  */
674  static LuaRef newTable (lua_State* L)
675  {
676    lua_newtable (L);
677    return LuaRef (L, FromStack ());
678  }
679
680  //----------------------------------------------------------------------------
681  /**
682      Return a reference to a named global.
683
684      It is also possible to use the free function `getGlobal`.
685
686      @see ::getGlobal
687  */
688  static LuaRef getGlobal (lua_State *L, char const* name)
689  {
690    lua_getglobal (L, name);
691    return LuaRef (L, FromStack ());
692  }
693
694  //----------------------------------------------------------------------------
695  /**
696      Assign a different value to this LuaRef.
697  */
698  template <class T>
699  LuaRef& operator= (T rhs)
700  {
701    luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
702    Stack <T>::push (m_L, rhs);
703    m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
704    return *this;
705  }
706
707  //----------------------------------------------------------------------------
708  /**
709      Assign another LuaRef to this LuaRef.
710  */
711  LuaRef& operator= (LuaRef const& rhs)
712  {
713    luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
714    rhs.push (m_L);
715    m_L = rhs.state ();
716    m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
717    return *this;
718  }
719
720  //----------------------------------------------------------------------------
721  /**
722      converts to a string using luas tostring function
723  */
724  std::string tostring() const
725  {
726    lua_getglobal (m_L, "tostring");
727    push (m_L);
728    lua_call (m_L, 1, 1);
729    const char* str = lua_tostring(m_L, 1);
730    lua_pop(m_L, 1);
731    return std::string(str);
732  }
733
734  //----------------------------------------------------------------------------
735  /**
736      Print a text description of the value to a stream.
737
738      This is used for diagnostics.
739  */
740  void print (std::ostream& os) const
741  {
742    switch (type ())
743    {
744    case LUA_TNIL:
745      os << "nil";
746      break;
747
748    case LUA_TNUMBER:
749      os << cast <lua_Number> ();
750      break;
751
752    case LUA_TBOOLEAN:
753      os << (cast <bool> () ? "true" : "false");
754      break;
755
756    case LUA_TSTRING:
757      os << '"' << cast <std::string> () << '"';
758      break;
759
760    case LUA_TTABLE:
761      os << "table: " << tostring();
762      break;
763
764    case LUA_TFUNCTION:
765      os << "function: " << tostring();
766      break;
767
768    case LUA_TUSERDATA:
769      os << "userdata: " << tostring();
770      break;
771
772    case LUA_TTHREAD:
773      os << "thread: " << tostring();
774      break;
775
776    case LUA_TLIGHTUSERDATA:
777      os << "lightuserdata: " << tostring();
778      break;
779
780    default:
781      os << "unknown";
782      break;
783    }
784  }
785
786  //============================================================================
787  //
788  // This group of member functions is mirrored in Proxy
789  //
790
791  /** Retrieve the lua_State associated with the reference.
792  */
793  lua_State* state () const
794  {
795    return m_L;
796  }
797
798  //----------------------------------------------------------------------------
799  /**
800      Place the object onto the Lua stack.
801  */
802  void push (lua_State* L) const
803  {
804    assert (equalstates (L, m_L));
805    lua_rawgeti (L, LUA_REGISTRYINDEX, m_ref);
806  }
807
808  //----------------------------------------------------------------------------
809  /**
810      Pop the top of Lua stack and assign the ref to m_ref
811  */
812  void pop (lua_State* L)
813  {
814    assert (equalstates (L, m_L));
815    luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
816    m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
817  }
818
819  //----------------------------------------------------------------------------
820  /**
821      Determine the object type.
822
823      The return values are the same as for `lua_type`.
824  */
825  /** @{ */
826  int type () const
827  {
828    int result;
829    if (m_ref != LUA_REFNIL)
830    {
831      push (m_L);
832      result = lua_type (m_L, -1);
833      lua_pop (m_L, 1);
834    }
835    else
836    {
837      result = LUA_TNIL;
838    }
839
840    return result;
841  }
842
843  // should never happen
844  //inline bool isNone () const { return m_ref == LUA_NOREF; }
845
846  inline bool isNil () const { return type () == LUA_TNIL; }
847  inline bool isNumber () const { return type () == LUA_TNUMBER; }
848  inline bool isString () const { return type () == LUA_TSTRING; }
849  inline bool isTable () const { return type () == LUA_TTABLE; }
850  inline bool isFunction () const { return type () == LUA_TFUNCTION; }
851  inline bool isUserdata () const { return type () == LUA_TUSERDATA; }
852  inline bool isThread () const { return type () == LUA_TTHREAD; }
853  inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
854  /** @} */
855
856  //----------------------------------------------------------------------------
857  /**
858      Perform an explicit conversion.
859  */
860  template <class T>
861  T cast () const
862  {
863    StackPop p (m_L, 1);
864    push (m_L);
865
866    // lua_gettop is used because Userdata::getClass() doesn't handle
867    // negative stack indexes.
868    //
869    return Stack <T>::get (m_L, lua_gettop (m_L));
870  }
871
872  //----------------------------------------------------------------------------
873  /**
874      Universal implicit conversion operator.
875
876      NOTE: Visual Studio 2010 and 2012 have a bug where this function
877            is not used. See:
878
879      http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
880      https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
881
882          // This code snippet fails to compile in vs2010,vs2012
883          struct S {
884            template <class T> inline operator T () const { return T (); }
885          };
886          int main () {
887            S () || false;
888            return 0;
889          }
890  */
891  template <class T>
892  inline operator T () const
893  {
894    return cast <T> ();
895  }
896
897  //----------------------------------------------------------------------------
898  /**
899      Universal comparison operators.
900  */
901  /** @{ */
902  template <class T>
903  bool operator== (T rhs) const
904  {
905    StackPop p (m_L, 2);
906    push (m_L);
907    Stack <T>::push (m_L, rhs);
908    return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
909  }
910
911  template <class T>
912  bool operator< (T rhs) const
913  {
914    StackPop p (m_L, 2);
915    push (m_L);
916    Stack <T>::push (m_L, rhs);
917    return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
918  }
919
920  template <class T>
921  bool operator<= (T rhs) const
922  {
923    StackPop p (m_L, 2);
924    push (m_L);
925    Stack <T>::push (m_L, rhs);
926    return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
927  }
928
929  template <class T>
930  bool operator> (T rhs) const
931  {
932    StackPop p (m_L, 2);
933    push (m_L);
934    Stack <T>::push (m_L, rhs);
935    return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
936  }
937
938  template <class T>
939  bool operator>= (T rhs) const
940  {
941    StackPop p (m_L, 2);
942    push (m_L);
943    Stack <T>::push (m_L, rhs);
944    return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
945  }
946
947  template <class T>
948  bool rawequal (T rhs) const
949  {
950    StackPop p (m_L, 2);
951    push (m_L);
952    Stack <T>::push (m_L, rhs);
953    return lua_rawequal (m_L, -1, -2) == 1;
954  }
955  /** @} */
956
957  //----------------------------------------------------------------------------
958  /**
959      Append a value to the table.
960
961      If the table is a sequence this will add another element to it.
962  */
963  template <class T>
964  void append (T v) const
965  {
966    push (m_L);
967    Stack <T>::push (m_L, v);
968    luaL_ref (m_L, -2);
969    lua_pop (m_L, 1);
970  }
971
972  //----------------------------------------------------------------------------
973  /**
974      Call the length operator.
975
976      This is identical to applying the Lua # operator.
977  */
978  int length () const
979  {
980    StackPop p (m_L, 1);
981    push (m_L);
982    return get_length (m_L, -1);
983  }
984
985  //----------------------------------------------------------------------------
986  /**
987      Access a table value using a key.
988
989      This invokes metamethods.
990  */
991  template <class T>
992  Proxy operator[] (T key) const
993  {
994    Stack <T>::push (m_L, key);
995    return Proxy (m_L, m_ref);
996  }
997
998  //----------------------------------------------------------------------------
999  /**
1000      Call Lua code.
1001
1002      These overloads allow Lua code to be called with up to 8 parameters.
1003      The return value is provided as a LuaRef (which may be LUA_REFNIL).
1004      If an error occurs, a LuaException is thrown.
1005  */
1006  /** @{ */
1007  LuaRef const operator() () const
1008  {
1009    push (m_L);
1010    LuaException::pcall (m_L, 0, 1);
1011    return LuaRef (m_L, FromStack ());
1012  }
1013
1014  template <class P1>
1015  LuaRef const operator() (P1 p1) const
1016  {
1017    push (m_L);
1018    Stack <P1>::push (m_L, p1);
1019    LuaException::pcall (m_L, 1, 1);
1020    return LuaRef (m_L, FromStack ());
1021  }
1022
1023  template <class P1, class P2>
1024  LuaRef const operator() (P1 p1, P2 p2) const
1025  {
1026    push (m_L);
1027    Stack <P1>::push (m_L, p1);
1028    Stack <P2>::push (m_L, p2);
1029    LuaException::pcall (m_L, 2, 1);
1030    return LuaRef (m_L, FromStack ());
1031  }
1032
1033  template <class P1, class P2, class P3>
1034  LuaRef const operator() (P1 p1, P2 p2, P3 p3) const
1035  {
1036    push (m_L);
1037    Stack <P1>::push (m_L, p1);
1038    Stack <P2>::push (m_L, p2);
1039    Stack <P3>::push (m_L, p3);
1040    LuaException::pcall (m_L, 3, 1);
1041    return LuaRef (m_L, FromStack ());
1042  }
1043
1044  template <class P1, class P2, class P3, class P4>
1045  LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
1046  {
1047    push (m_L);
1048    Stack <P1>::push (m_L, p1);
1049    Stack <P2>::push (m_L, p2);
1050    Stack <P3>::push (m_L, p3);
1051    Stack <P4>::push (m_L, p4);
1052    LuaException::pcall (m_L, 4, 1);
1053    return LuaRef (m_L, FromStack ());
1054  }
1055
1056  template <class P1, class P2, class P3, class P4, class P5>
1057  LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
1058  {
1059    push (m_L);
1060    Stack <P1>::push (m_L, p1);
1061    Stack <P2>::push (m_L, p2);
1062    Stack <P3>::push (m_L, p3);
1063    Stack <P4>::push (m_L, p4);
1064    Stack <P5>::push (m_L, p5);
1065    LuaException::pcall (m_L, 5, 1);
1066    return LuaRef (m_L, FromStack ());
1067  }
1068
1069  template <class P1, class P2, class P3, class P4, class P5, class P6>
1070  LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
1071  {
1072    push (m_L);
1073    Stack <P1>::push (m_L, p1);
1074    Stack <P2>::push (m_L, p2);
1075    Stack <P3>::push (m_L, p3);
1076    Stack <P4>::push (m_L, p4);
1077    Stack <P5>::push (m_L, p5);
1078    Stack <P6>::push (m_L, p6);
1079    LuaException::pcall (m_L, 6, 1);
1080    return LuaRef (m_L, FromStack ());
1081  }
1082
1083  template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
1084  LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
1085  {
1086    push (m_L);
1087    Stack <P1>::push (m_L, p1);
1088    Stack <P2>::push (m_L, p2);
1089    Stack <P3>::push (m_L, p3);
1090    Stack <P4>::push (m_L, p4);
1091    Stack <P5>::push (m_L, p5);
1092    Stack <P6>::push (m_L, p6);
1093    Stack <P7>::push (m_L, p7);
1094    LuaException::pcall (m_L, 7, 1);
1095    return LuaRef (m_L, FromStack ());
1096  }
1097
1098  template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
1099  LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
1100  {
1101    push (m_L);
1102    Stack <P1>::push (m_L, p1);
1103    Stack <P2>::push (m_L, p2);
1104    Stack <P3>::push (m_L, p3);
1105    Stack <P4>::push (m_L, p4);
1106    Stack <P5>::push (m_L, p5);
1107    Stack <P6>::push (m_L, p6);
1108    Stack <P7>::push (m_L, p7);
1109    Stack <P8>::push (m_L, p8);
1110    LuaException::pcall (m_L, 8, 1);
1111    return LuaRef (m_L, FromStack ());
1112  }
1113  /** @} */
1114
1115  //============================================================================
1116
1117private:
1118  lua_State* m_L;
1119  int m_ref;
1120};
1121
1122//------------------------------------------------------------------------------
1123/**
1124    Stack specialization for Nil
1125*/
1126template <>
1127struct Stack <Nil>
1128{
1129public:
1130  static inline void push (lua_State* L, Nil)
1131  {
1132    lua_pushnil (L);
1133  }
1134};
1135
1136//------------------------------------------------------------------------------
1137/**
1138    Stack specialization for LuaRef.
1139*/
1140template <>
1141struct Stack <LuaRef>
1142{
1143public:
1144  // The value is const& to prevent a copy construction.
1145  //
1146  static inline void push (lua_State* L, LuaRef const& v)
1147  {
1148    v.push (L);
1149  }
1150
1151  static inline LuaRef get (lua_State* L, int index)
1152  {
1153    return LuaRef (L, index, LuaRef::FromStack ());
1154  }
1155};
1156
1157//------------------------------------------------------------------------------
1158/**
1159    Stack specialization for Proxy.
1160*/
1161template <>
1162struct Stack <LuaRef::Proxy>
1163{
1164public:
1165  // The value is const& to prevent a copy construction.
1166  //
1167  static inline void push (lua_State* L, LuaRef::Proxy const& v)
1168  {
1169    v.push (L);
1170  }
1171};
1172
1173//------------------------------------------------------------------------------
1174/**
1175    Create a reference to a new, empty table.
1176
1177    This is a syntactic abbreviation for LuaRef::newTable().
1178*/
1179inline LuaRef newTable (lua_State* L)
1180{
1181  return LuaRef::newTable (L);
1182}
1183
1184//------------------------------------------------------------------------------
1185/**
1186    Create a reference to a value in the global table.
1187
1188    This is a syntactic abbreviation for LuaRef::getGlobal().
1189*/
1190inline LuaRef getGlobal (lua_State *L, char const* name)
1191{
1192  return LuaRef::getGlobal (L, name);
1193}
1194
1195//------------------------------------------------------------------------------
1196/**
1197    Write a LuaRef to a stream.
1198
1199    This allows LuaRef and table proxies to work with streams.
1200*/
1201inline std::ostream& operator<< (std::ostream& os, LuaRef const& ref)
1202{
1203  ref.print (os);
1204  return os;
1205}
1206
1207//------------------------------------------------------------------------------
1208
1209// more C++-like cast syntax
1210//
1211template<class T>
1212inline T LuaRef_cast(LuaRef const& lr)
1213{
1214  return lr.cast<T>();
1215}
Property changes on: trunk/src/lib/lua/bridge/detail/LuaRef.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/LuaException.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@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
30class LuaException : public std::exception
31{
32private:
33  lua_State* m_L;
34  std::string m_what;
35
36public:
37  //----------------------------------------------------------------------------
38  /**
39      Construct a LuaException after a lua_pcall().
40  */
41  LuaException (lua_State* L, int /*code*/)
42    : m_L (L)
43  {
44    whatFromStack ();
45  }
46
47  //----------------------------------------------------------------------------
48
49  LuaException (lua_State *L,
50                char const*,
51                char const*,
52                long)
53    : m_L (L)
54  {
55    whatFromStack ();
56  }
57
58  //----------------------------------------------------------------------------
59
60  ~LuaException() throw ()
61  {
62  }
63
64  //----------------------------------------------------------------------------
65
66  char const* what() const throw ()
67  {
68    return m_what.c_str();
69  }
70
71  //============================================================================
72  /**
73      Throw an exception.
74
75      This centralizes all the exceptions thrown, so that we can set
76      breakpoints before the stack is unwound, or otherwise customize the
77      behavior.
78  */
79  template <class Exception>
80  static void Throw (Exception e)
81  {
82    throw e;
83  }
84
85  //----------------------------------------------------------------------------
86  /**
87      Wrapper for lua_pcall that throws.
88  */
89  static void pcall (lua_State* L, int nargs = 0, int nresults = 0, int msgh = 0)
90  {
91    int code = lua_pcall (L, nargs, nresults, msgh);
92
93    if (code != LUABRIDGE_LUA_OK)
94      Throw (LuaException (L, code));
95  }
96
97  //----------------------------------------------------------------------------
98
99protected:
100  void whatFromStack ()
101  {
102    if (lua_gettop (m_L) > 0)
103    {
104      char const* s = lua_tostring (m_L, -1);
105      m_what = s ? s : "";
106    }
107    else
108    {
109      // stack is empty
110      m_what = "missing error";
111    }
112  }
113};
Property changes on: trunk/src/lib/lua/bridge/detail/LuaException.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/ClassInfo.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6
7  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
8
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26*/
27//==============================================================================
28
29/** Unique Lua registry keys for a class.
30
31    Each registered class inserts three keys into the registry, whose
32    values are the corresponding static, class, and const metatables. This
33    allows a quick and reliable lookup for a metatable from a template type.
34*/
35template <class T>
36class ClassInfo
37{
38public:
39  /** Get the key for the static table.
40
41      The static table holds the static data members, static properties, and
42      static member functions for a class.
43  */
44  static void const* getStaticKey ()
45  {
46    static char value;
47    return &value;
48  }
49
50  /** Get the key for the class table.
51
52      The class table holds the data members, properties, and member functions
53      of a class. Read-only data and properties, and const member functions are
54      also placed here (to save a lookup in the const table).
55  */
56  static void const* getClassKey ()
57  {
58    static char value;
59    return &value;
60  }
61
62  /** Get the key for the const table.
63
64      The const table holds read-only data members and properties, and const
65      member functions of a class.
66  */
67  static void const* getConstKey ()
68  {
69    static char value;
70    return &value;
71  }
72};
73
Property changes on: trunk/src/lib/lua/bridge/detail/ClassInfo.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/FuncTraits.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6
7  License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
8
9  Permission is hereby granted, free of charge, to any person obtaining a copy
10  of this software and associated documentation files (the "Software"), to deal
11  in the Software without restriction, including without limitation the rights
12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  copies of the Software, and to permit persons to whom the Software is
14  furnished to do so, subject to the following conditions:
15
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26*/
27//==============================================================================
28
29/**
30  Since the throw specification is part of a function signature, the FuncTraits
31  family of templates needs to be specialized for both types. The
32  LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or
33  'noexcept' (if C++11 is available) to distinguish the functions.
34*/
35#if defined (__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__clang__) || defined(__GNUC__) || \
36    (defined (_MSC_VER) && (_MSC_VER >= 1700))
37// Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc  compilers do not
38// distinguish the throw specification in the function signature.
39#else
40// Visual Studio 10 and earlier pay too much mind to useless throw() spec.
41//
42# define LUABRIDGE_THROWSPEC throw()
43#endif
44
45//==============================================================================
46/**
47    Traits for function pointers.
48
49    There are three types of functions: global, non-const member, and const
50    member. These templates determine the type of function, which class type it
51    belongs to if it is a class member, the const-ness if it is a member
52    function, and the type information for the return value and argument list.
53
54    Expansions are provided for functions with up to 8 parameters. This can be
55    manually extended, or expanded to an arbitrary amount using C++11 features.
56*/
57template <class MemFn, class D = MemFn>
58struct FuncTraits
59{
60};
61
62/* Ordinary function pointers. */
63
64template <class R, class D>
65struct FuncTraits <R (*) (), D>
66{
67  static bool const isMemberFunction = false;
68  typedef D DeclType;
69  typedef R ReturnType;
70  typedef None Params;
71  static R call (D fp, TypeListValues <Params>)
72  {
73    return fp ();
74  }
75};
76
77template <class R, class P1, class D>
78struct FuncTraits <R (*) (P1), D>
79{
80  static bool const isMemberFunction = false;
81  typedef D DeclType;
82  typedef R ReturnType;
83  typedef TypeList <P1> Params;
84  static R call (D fp, TypeListValues <Params> tvl)
85  {
86    return fp (tvl.hd);
87  }
88};
89
90template <class R, class P1, class P2, class D>
91struct FuncTraits <R (*) (P1, P2), D>
92{
93  static bool const isMemberFunction = false;
94  typedef D DeclType;
95  typedef R ReturnType;
96  typedef TypeList <P1, TypeList <P2> > Params;
97  static R call (D fp, TypeListValues <Params> tvl)
98  {
99    return fp (tvl.hd, tvl.tl.hd);
100  }
101};
102
103template <class R, class P1, class P2, class P3, class D>
104struct FuncTraits <R (*) (P1, P2, P3), D>
105{
106  static bool const isMemberFunction = false;
107  typedef D DeclType;
108  typedef R ReturnType;
109  typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
110  static R call (D fp, TypeListValues <Params> tvl)
111  {
112    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
113  }
114};
115
116template <class R, class P1, class P2, class P3, class P4, class D>
117struct FuncTraits <R (*) (P1, P2, P3, P4), D>
118{
119  static bool const isMemberFunction = false;
120  typedef D DeclType;
121  typedef R ReturnType;
122  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
123  static R call (D fp, TypeListValues <Params> tvl)
124  {
125    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
126  }
127};
128
129template <class R, class P1, class P2, class P3, class P4, class P5, class D>
130struct FuncTraits <R (*) (P1, P2, P3, P4, P5), D>
131{
132  static bool const isMemberFunction = false;
133  typedef D DeclType;
134  typedef R ReturnType;
135  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
136  static R call (D fp, TypeListValues <Params> tvl)
137  {
138    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
139  }
140};
141
142template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
143struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6), D>
144{
145  static bool const isMemberFunction = false;
146  typedef D DeclType;
147  typedef R ReturnType;
148  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5,  TypeList <P6> > > > > > Params;
149  static R call (D fp, TypeListValues <Params> tvl)
150  {
151    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
152  }
153};
154
155template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
156struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7), D>
157{
158  static bool const isMemberFunction = false;
159  typedef D DeclType;
160  typedef R ReturnType;
161  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
162  static R call (D fp, TypeListValues <Params> tvl)
163  {
164    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
165  }
166};
167
168template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
169struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8), D>
170{
171  static bool const isMemberFunction = false;
172  typedef D DeclType;
173  typedef R ReturnType;
174  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
175  static R call (D fp, TypeListValues <Params> tvl)
176  {
177    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
178  }
179};
180
181/* Non-const member function pointers. */
182
183template <class T, class R, class D>
184struct FuncTraits <R (T::*) (), D>
185{
186  static bool const isMemberFunction = true;
187  static bool const isConstMemberFunction = false;
188  typedef D DeclType;
189  typedef T ClassType;
190  typedef R ReturnType;
191  typedef None Params;
192  static R call (T* obj, D fp, TypeListValues <Params>)
193  {
194    return (obj->*fp)();
195  }
196};
197
198template <class T, class R, class P1, class D>
199struct FuncTraits <R (T::*) (P1), D>
200{
201  static bool const isMemberFunction = true;
202  static bool const isConstMemberFunction = false;
203  typedef D DeclType;
204  typedef T ClassType;
205  typedef R ReturnType;
206  typedef TypeList <P1> Params;
207  static R call (T* obj, D fp, TypeListValues <Params> tvl)
208  {
209    return (obj->*fp)(tvl.hd);
210  }
211};
212
213template <class T, class R, class P1, class P2, class D>
214struct FuncTraits <R (T::*) (P1, P2), D>
215{
216  static bool const isMemberFunction = true;
217  static bool const isConstMemberFunction = false;
218  typedef D DeclType;
219  typedef T ClassType;
220  typedef R ReturnType;
221  typedef TypeList <P1, TypeList <P2> > Params;
222  static R call (T* obj, D fp, TypeListValues <Params> tvl)
223  {
224    return (obj->*fp)(tvl.hd, tvl.tl.hd);
225  }
226};
227
228template <class T, class R, class P1, class P2, class P3, class D>
229struct FuncTraits <R (T::*) (P1, P2, P3), D>
230{
231  static bool const isMemberFunction = true;
232  static bool const isConstMemberFunction = false;
233  typedef D DeclType;
234  typedef T ClassType;
235  typedef R ReturnType;
236  typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
237  static R call (T* obj, D fp, TypeListValues <Params> tvl)
238  {
239    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
240  }
241};
242
243template <class T, class R, class P1, class P2, class P3, class P4, class D>
244struct FuncTraits <R (T::*) (P1, P2, P3, P4), D>
245{
246  static bool const isMemberFunction = true;
247  static bool const isConstMemberFunction = false;
248  typedef D DeclType;
249  typedef T ClassType;
250  typedef R ReturnType;
251  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
252  static R call (T* obj, D fp, TypeListValues <Params> tvl)
253  {
254    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
255  }
256};
257
258template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
259struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5), D>
260{
261  static bool const isMemberFunction = true;
262  static bool const isConstMemberFunction = false;
263  typedef D DeclType;
264  typedef T ClassType;
265  typedef R ReturnType;
266  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
267  static R call (T* obj, D fp, TypeListValues <Params> tvl)
268  {
269    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
270  }
271};
272
273template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
274struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6), D>
275{
276  static bool const isMemberFunction = true;
277  static bool const isConstMemberFunction = false;
278  typedef D DeclType;
279  typedef T ClassType;
280  typedef R ReturnType;
281  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
282  static R call (T* obj, D fp, TypeListValues <Params> tvl)
283  {
284    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
285  }
286};
287
288template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
289struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7), D>
290{
291  static bool const isMemberFunction = true;
292  static bool const isConstMemberFunction = false;
293  typedef D DeclType;
294  typedef T ClassType;
295  typedef R ReturnType;
296  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
297  static R call (T* obj, D fp, TypeListValues <Params> tvl)
298  {
299    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
300  }
301};
302
303template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
304struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8), D>
305{
306  static bool const isMemberFunction = true;
307  static bool const isConstMemberFunction = false;
308  typedef D DeclType;
309  typedef T ClassType;
310  typedef R ReturnType;
311  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
312  static R call (T* obj, D fp, TypeListValues <Params> tvl)
313  {
314    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
315  }
316};
317
318/* Const member function pointers. */
319
320template <class T, class R, class D>
321struct FuncTraits <R (T::*) () const, D>
322{
323  static bool const isMemberFunction = true;
324  static bool const isConstMemberFunction = true;
325  typedef D DeclType;
326  typedef T ClassType;
327  typedef R ReturnType;
328  typedef None Params;
329  static R call (T const* obj, D fp, TypeListValues <Params>)
330  {
331    return (obj->*fp)();
332  }
333};
334
335template <class T, class R, class P1, class D>
336struct FuncTraits <R (T::*) (P1) const, D>
337{
338  static bool const isMemberFunction = true;
339  static bool const isConstMemberFunction = true;
340  typedef D DeclType;
341  typedef T ClassType;
342  typedef R ReturnType;
343  typedef TypeList <P1> Params;
344  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
345  {
346    return (obj->*fp)(tvl.hd);
347  }
348};
349
350template <class T, class R, class P1, class P2, class D>
351struct FuncTraits <R (T::*) (P1, P2) const, D>
352{
353  static bool const isMemberFunction = true;
354  static bool const isConstMemberFunction = true;
355  typedef D DeclType;
356  typedef T ClassType;
357  typedef R ReturnType;
358  typedef TypeList <P1, TypeList <P2> > Params;
359  static R call (T const* obj, R (T::*fp) (P1, P2) const,
360    TypeListValues <Params> tvl)
361  {
362    return (obj->*fp)(tvl.hd, tvl.tl.hd);
363  }
364};
365
366template <class T, class R, class P1, class P2, class P3, class D>
367struct FuncTraits <R (T::*) (P1, P2, P3) const, D>
368{
369  static bool const isMemberFunction = true;
370  static bool const isConstMemberFunction = true;
371  typedef D DeclType;
372  typedef T ClassType;
373  typedef R ReturnType;
374  typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
375  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
376  {
377    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
378  }
379};
380
381template <class T, class R, class P1, class P2, class P3, class P4, class D>
382struct FuncTraits <R (T::*) (P1, P2, P3, P4) const, D>
383{
384  static bool const isMemberFunction = true;
385  static bool const isConstMemberFunction = true;
386  typedef D DeclType;
387  typedef T ClassType;
388  typedef R ReturnType;
389  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
390  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
391  {
392    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
393  }
394};
395
396template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
397struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const, D>
398{
399  static bool const isMemberFunction = true;
400  static bool const isConstMemberFunction = true;
401  typedef D DeclType;
402  typedef T ClassType;
403  typedef R ReturnType;
404  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
405  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
406  {
407    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
408  }
409};
410
411template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
412struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const, D>
413{
414  static bool const isMemberFunction = true;
415  static bool const isConstMemberFunction = true;
416  typedef D DeclType;
417  typedef T ClassType;
418  typedef R ReturnType;
419  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
420  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
421  {
422    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
423  }
424};
425
426template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
427struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const, D>
428{
429  static bool const isMemberFunction = true;
430  static bool const isConstMemberFunction = true;
431  typedef D DeclType;
432  typedef T ClassType;
433  typedef R ReturnType;
434  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
435  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
436  {
437    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
438  }
439};
440
441template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
442struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const, D>
443{
444  static bool const isMemberFunction = true;
445  static bool const isConstMemberFunction = true;
446  typedef D DeclType;
447  typedef T ClassType;
448  typedef R ReturnType;
449  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
450  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
451  {
452    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
453  }
454};
455
456#if defined (LUABRIDGE_THROWSPEC)
457
458/* Ordinary function pointers. */
459
460template <class R, class D>
461struct FuncTraits <R (*) () LUABRIDGE_THROWSPEC, D>
462{
463  static bool const isMemberFunction = false;
464  typedef D DeclType;
465  typedef R ReturnType;
466  typedef None Params;
467  static R call (D fp, TypeListValues <Params> const&)
468  {
469    return fp ();
470  }
471};
472
473template <class R, class P1, class D>
474struct FuncTraits <R (*) (P1) LUABRIDGE_THROWSPEC, D>
475{
476  static bool const isMemberFunction = false;
477  typedef D DeclType;
478  typedef R ReturnType;
479  typedef TypeList <P1> Params;
480  static R call (D fp, TypeListValues <Params> tvl)
481  {
482    return fp (tvl.hd);
483  }
484};
485
486template <class R, class P1, class P2, class D>
487struct FuncTraits <R (*) (P1, P2) LUABRIDGE_THROWSPEC, D>
488{
489  static bool const isMemberFunction = false;
490  typedef D DeclType;
491  typedef R ReturnType;
492  typedef TypeList <P1, TypeList <P2> > Params;
493  static R call (D fp, TypeListValues <Params> tvl)
494  {
495    return fp (tvl.hd, tvl.tl.hd);
496  }
497};
498
499template <class R, class P1, class P2, class P3, class D>
500struct FuncTraits <R (*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D>
501{
502  static bool const isMemberFunction = false;
503  typedef D DeclType;
504  typedef R ReturnType;
505  typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
506  static R call (D fp, TypeListValues <Params> tvl)
507  {
508    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
509  }
510};
511
512template <class R, class P1, class P2, class P3, class P4, class D>
513struct FuncTraits <R (*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D>
514{
515  static bool const isMemberFunction = false;
516  typedef D DeclType;
517  typedef R ReturnType;
518  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
519  static R call (D fp, TypeListValues <Params> tvl)
520  {
521    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
522  }
523};
524
525template <class R, class P1, class P2, class P3, class P4, class P5, class D>
526struct FuncTraits <R (*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D>
527{
528  static bool const isMemberFunction = false;
529  typedef D DeclType;
530  typedef R ReturnType;
531  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
532  static R call (D fp, TypeListValues <Params> tvl)
533  {
534    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
535  }
536};
537
538template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
539struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D>
540{
541  static bool const isMemberFunction = false;
542  typedef D DeclType;
543  typedef R ReturnType;
544  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5,  TypeList <P6> > > > > > Params;
545  static R call (D fp, TypeListValues <Params> tvl)
546  {
547    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
548  }
549};
550
551template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
552struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D>
553{
554  static bool const isMemberFunction = false;
555  typedef D DeclType;
556  typedef R ReturnType;
557  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
558  static R call (D fp, TypeListValues <Params> tvl)
559  {
560    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
561  }
562};
563
564template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
565struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D>
566{
567  static bool const isMemberFunction = false;
568  typedef D DeclType;
569  typedef R ReturnType;
570  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
571  static R call (D fp, TypeListValues <Params> tvl)
572  {
573    return fp (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
574  }
575};
576
577/* Non-const member function pointers with THROWSPEC. */
578
579template <class T, class R, class D>
580struct FuncTraits <R (T::*) () LUABRIDGE_THROWSPEC, D>
581{
582  static bool const isMemberFunction = true;
583  static bool const isConstMemberFunction = false;
584  typedef D DeclType;
585  typedef T ClassType;
586  typedef R ReturnType;
587  typedef None Params;
588  static R call (T* obj, D fp, TypeListValues <Params> const&)
589  {
590    return (obj->*fp)();
591  }
592};
593
594template <class T, class R, class P1, class D>
595struct FuncTraits <R (T::*) (P1) LUABRIDGE_THROWSPEC, D>
596{
597  static bool const isMemberFunction = true;
598  static bool const isConstMemberFunction = false;
599  typedef D DeclType;
600  typedef T ClassType;
601  typedef R ReturnType;
602  typedef TypeList <P1> Params;
603  static R call (T* obj, D fp, TypeListValues <Params> tvl)
604  {
605    return (obj->*fp)(tvl.hd);
606  }
607};
608
609template <class T, class R, class P1, class P2, class D>
610struct FuncTraits <R (T::*) (P1, P2) LUABRIDGE_THROWSPEC, D>
611{
612  static bool const isMemberFunction = true;
613  static bool const isConstMemberFunction = false;
614  typedef D DeclType;
615  typedef T ClassType;
616  typedef R ReturnType;
617  typedef TypeList <P1, TypeList <P2> > Params;
618  static R call (T* obj, D fp, TypeListValues <Params> tvl)
619  {
620    return (obj->*fp)(tvl.hd, tvl.tl.hd);
621  }
622};
623
624template <class T, class R, class P1, class P2, class P3, class D>
625struct FuncTraits <R (T::*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D>
626{
627  static bool const isMemberFunction = true;
628  static bool const isConstMemberFunction = false;
629  typedef D DeclType;
630  typedef T ClassType;
631  typedef R ReturnType;
632  typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
633  static R call (T* obj, D fp, TypeListValues <Params> tvl)
634  {
635    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
636  }
637};
638
639template <class T, class R, class P1, class P2, class P3, class P4, class D>
640struct FuncTraits <R (T::*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D>
641{
642  static bool const isMemberFunction = true;
643  static bool const isConstMemberFunction = false;
644  typedef D DeclType;
645  typedef T ClassType;
646  typedef R ReturnType;
647  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
648  static R call (T* obj, D fp, TypeListValues <Params> tvl)
649  {
650    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
651  }
652};
653
654template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
655struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D>
656{
657  static bool const isMemberFunction = true;
658  static bool const isConstMemberFunction = false;
659  typedef D DeclType;
660  typedef T ClassType;
661  typedef R ReturnType;
662  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
663  static R call (T* obj, D fp, TypeListValues <Params> tvl)
664  {
665    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
666  }
667};
668
669template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
670struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D>
671{
672  static bool const isMemberFunction = true;
673  static bool const isConstMemberFunction = false;
674  typedef D DeclType;
675  typedef T ClassType;
676  typedef R ReturnType;
677  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
678  static R call (T* obj, D fp, TypeListValues <Params> tvl)
679  {
680    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
681  }
682};
683
684template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
685struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D>
686{
687  static bool const isMemberFunction = true;
688  static bool const isConstMemberFunction = false;
689  typedef D DeclType;
690  typedef T ClassType;
691  typedef R ReturnType;
692  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
693  static R call (T* obj, D fp, TypeListValues <Params> tvl)
694  {
695    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
696  }
697};
698
699template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
700struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D>
701{
702  static bool const isMemberFunction = true;
703  static bool const isConstMemberFunction = false;
704  typedef D DeclType;
705  typedef T ClassType;
706  typedef R ReturnType;
707  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
708  static R call (T* obj, D fp, TypeListValues <Params> tvl)
709  {
710    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
711  }
712};
713
714/* Const member function pointers with THROWSPEC. */
715
716template <class T, class R, class D>
717struct FuncTraits <R (T::*) () const LUABRIDGE_THROWSPEC, D>
718{
719  static bool const isMemberFunction = true;
720  static bool const isConstMemberFunction = true;
721  typedef D DeclType;
722  typedef T ClassType;
723  typedef R ReturnType;
724  typedef None Params;
725  static R call (T const* obj, D fp, TypeListValues <Params>)
726  {
727    return (obj->*fp)();
728  }
729};
730
731template <class T, class R, class P1, class D>
732struct FuncTraits <R (T::*) (P1) const LUABRIDGE_THROWSPEC, D>
733{
734  static bool const isMemberFunction = true;
735  static bool const isConstMemberFunction = true;
736  typedef D DeclType;
737  typedef T ClassType;
738  typedef R ReturnType;
739  typedef TypeList <P1> Params;
740  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
741  {
742    return (obj->*fp)(tvl.hd);
743  }
744};
745
746template <class T, class R, class P1, class P2, class D>
747struct FuncTraits <R (T::*) (P1, P2) const LUABRIDGE_THROWSPEC, D>
748{
749  static bool const isMemberFunction = true;
750  static bool const isConstMemberFunction = true;
751  typedef D DeclType;
752  typedef T ClassType;
753  typedef R ReturnType;
754  typedef TypeList <P1, TypeList <P2> > Params;
755  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
756  {
757    return (obj->*fp)(tvl.hd, tvl.tl.hd);
758  }
759};
760
761template <class T, class R, class P1, class P2, class P3, class D>
762struct FuncTraits <R (T::*) (P1, P2, P3) const LUABRIDGE_THROWSPEC, D>
763{
764  static bool const isMemberFunction = true;
765  static bool const isConstMemberFunction = true;
766  typedef D DeclType;
767  typedef T ClassType;
768  typedef R ReturnType;
769  typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
770  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
771  {
772    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
773  }
774};
775
776template <class T, class R, class P1, class P2, class P3, class P4, class D>
777struct FuncTraits <R (T::*) (P1, P2, P3, P4) const LUABRIDGE_THROWSPEC, D>
778{
779  static bool const isMemberFunction = true;
780  static bool const isConstMemberFunction = true;
781  typedef D DeclType;
782  typedef T ClassType;
783  typedef R ReturnType;
784  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
785  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
786  {
787    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
788  }
789};
790
791template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
792struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const LUABRIDGE_THROWSPEC, D>
793{
794  static bool const isMemberFunction = true;
795  static bool const isConstMemberFunction = true;
796  typedef D DeclType;
797  typedef T ClassType;
798  typedef R ReturnType;
799  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
800  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
801  {
802    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
803      tvl.tl.tl.tl.tl.hd);
804  }
805};
806
807template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
808struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const LUABRIDGE_THROWSPEC, D>
809{
810  static bool const isMemberFunction = true;
811  static bool const isConstMemberFunction = true;
812  typedef D DeclType;
813  typedef T ClassType;
814  typedef R ReturnType;
815  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
816  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
817  {
818    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
819  }
820};
821
822template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
823struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const LUABRIDGE_THROWSPEC, D>
824{
825  static bool const isMemberFunction = true;
826  static bool const isConstMemberFunction = true;
827  typedef D DeclType;
828  typedef T ClassType;
829  typedef R ReturnType;
830  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
831  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
832  {
833    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
834  }
835};
836
837template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
838struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const LUABRIDGE_THROWSPEC, D>
839{
840  static bool const isMemberFunction = true;
841  static bool const isConstMemberFunction = true;
842  typedef D DeclType;
843  typedef T ClassType;
844  typedef R ReturnType;
845  typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
846  static R call (T const* obj, D fp, TypeListValues <Params> tvl)
847  {
848    return (obj->*fp)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
849  }
850};
851
852#endif
Property changes on: trunk/src/lib/lua/bridge/detail/FuncTraits.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/LuaHelpers.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2007, Nathan Reed
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// These are for Lua versions prior to 5.2.0.
31//
32#if LUA_VERSION_NUM < 502
33inline int lua_absindex (lua_State* L, int idx)
34{
35  if (idx > LUA_REGISTRYINDEX && idx < 0)
36    return lua_gettop (L) + idx + 1;
37  else
38    return idx;
39}
40
41inline void lua_rawgetp (lua_State* L, int idx, void const* p)
42{
43  idx = lua_absindex (L, idx);
44  lua_pushlightuserdata (L, const_cast <void*> (p));
45  lua_rawget (L,idx);
46}
47
48inline void lua_rawsetp (lua_State* L, int idx, void const* p)
49{
50  idx = lua_absindex (L, idx);
51  lua_pushlightuserdata (L, const_cast <void*> (p));
52  // put key behind value
53  lua_insert (L, -2);
54  lua_rawset (L, idx);
55}
56
57#define LUA_OPEQ 1
58#define LUA_OPLT 2
59#define LUA_OPLE 3
60
61inline int lua_compare (lua_State* L, int idx1, int idx2, int op)
62{
63  switch (op)
64  {
65  case LUA_OPEQ:
66    return lua_equal (L, idx1, idx2);
67    break;
68
69  case LUA_OPLT:
70    return lua_lessthan (L, idx1, idx2);
71    break;
72
73  case LUA_OPLE:
74    return lua_equal (L, idx1, idx2) || lua_lessthan (L, idx1, idx2);
75    break;
76
77  default:
78    return 0;
79  };
80}
81
82inline int get_length (lua_State* L, int idx)
83{
84  return int (lua_objlen (L, idx));
85}
86
87#else
88inline int get_length (lua_State* L, int idx)
89{
90  lua_len (L, idx);
91  int len = int (luaL_checknumber (L, -1));
92  lua_pop (L, 1);
93  return len;
94}
95
96#endif
97
98#ifndef LUA_OK
99# define LUABRIDGE_LUA_OK 0
100#else
101# define LUABRIDGE_LUA_OK LUA_OK
102#endif
103
104/** Get a table value, bypassing metamethods.
105*/ 
106inline void rawgetfield (lua_State* L, int index, char const* key)
107{
108  assert (lua_istable (L, index));
109  index = lua_absindex (L, index);
110  lua_pushstring (L, key);
111  lua_rawget (L, index);
112}
113
114/** Set a table value, bypassing metamethods.
115*/ 
116inline void rawsetfield (lua_State* L, int index, char const* key)
117{
118  assert (lua_istable (L, index));
119  index = lua_absindex (L, index);
120  lua_pushstring (L, key);
121  lua_insert (L, -2);
122  lua_rawset (L, index);
123}
124
125/** Returns true if the value is a full userdata (not light).
126*/
127inline bool isfulluserdata (lua_State* L, int index)
128{
129  return lua_isuserdata (L, index) && !lua_islightuserdata (L, index);
130}
131
132/** Test lua_State objects for global equality.
133
134    This can determine if two different lua_State objects really point
135    to the same global state, such as when using coroutines.
136
137    @note This is used for assertions.
138*/
139inline bool equalstates (lua_State* L1, lua_State* L2)
140{
141  return lua_topointer (L1, LUA_REGISTRYINDEX) ==
142         lua_topointer (L2, LUA_REGISTRYINDEX);
143}
Property changes on: trunk/src/lib/lua/bridge/detail/LuaHelpers.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/Constructor.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2007, Nathan Reed
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#ifndef LUABRIDGE_CONSTRUCTOR_HEADER
31#define LUABRIDGE_CONSTRUCTOR_HEADER
32
33/*
34* Constructor generators.  These templates allow you to call operator new and
35* pass the contents of a type/value list to the Constructor.  Like the
36* function pointer containers, these are only defined up to 8 parameters.
37*/
38
39/** Constructor generators.
40
41    These templates call operator new with the contents of a type/value
42    list passed to the Constructor with up to 8 parameters. Two versions
43    of call() are provided. One performs a regular new, the other performs
44    a placement new.
45*/
46template <class T, typename List>
47struct Constructor {};
48
49template <class T>
50struct Constructor <T, None>
51{
52  static T* call (TypeListValues <None> const&)
53  {
54    return new T;
55  }
56  static T* call (void* mem, TypeListValues <None> const&)
57  {
58    return new (mem) T;
59  }
60};
61
62template <class T, class P1>
63struct Constructor <T, TypeList <P1> >
64{
65  static T* call (const TypeListValues<TypeList <P1> > &tvl)
66  {
67    return new T(tvl.hd);
68  }
69  static T* call (void* mem, const TypeListValues<TypeList <P1> > &tvl)
70  {
71    return new (mem) T(tvl.hd);
72  }
73};
74
75template <class T, class P1, class P2>
76struct Constructor <T, TypeList <P1, TypeList <P2> > >
77{
78  static T* call (const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl)
79  {
80    return new T(tvl.hd, tvl.tl.hd);
81  }
82  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl)
83  {
84    return new (mem) T(tvl.hd, tvl.tl.hd);
85  }
86};
87
88template <class T, class P1, class P2, class P3>
89struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3> > > >
90{
91  static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
92    TypeList <P3> > > > &tvl)
93  {
94    return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
95  }
96  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
97    TypeList <P3> > > > &tvl)
98  {
99    return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
100  }
101};
102
103template <class T, class P1, class P2, class P3, class P4>
104struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
105  TypeList <P4> > > > >
106{
107  static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
108    TypeList <P3, TypeList <P4> > > > > &tvl)
109  {
110    return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
111  }
112  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
113    TypeList <P3, TypeList <P4> > > > > &tvl)
114  {
115    return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
116  }
117};
118
119template <class T, class P1, class P2, class P3, class P4,
120  class P5>
121struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
122  TypeList <P4, TypeList <P5> > > > > >
123{
124  static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
125    TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl)
126  {
127    return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
128      tvl.tl.tl.tl.tl.hd);
129  }
130  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
131    TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl)
132  {
133    return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
134      tvl.tl.tl.tl.tl.hd);
135  }
136};
137
138template <class T, class P1, class P2, class P3, class P4,
139  class P5, class P6>
140struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
141  TypeList <P4, TypeList <P5, TypeList <P6> > > > > > >
142{
143  static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
144    TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl)
145  {
146    return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
147      tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
148  }
149  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
150    TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl)
151  {
152    return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
153      tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
154  }
155};
156
157template <class T, class P1, class P2, class P3, class P4,
158  class P5, class P6, class P7>
159struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
160  TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > >
161{
162  static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
163    TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
164    TypeList <P7> > > > > > > > &tvl)
165  {
166    return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
167      tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
168      tvl.tl.tl.tl.tl.tl.tl.hd);
169  }
170  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
171    TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
172    TypeList <P7> > > > > > > > &tvl)
173  {
174    return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
175      tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
176      tvl.tl.tl.tl.tl.tl.tl.hd);
177  }
178};
179
180template <class T, class P1, class P2, class P3, class P4,
181  class P5, class P6, class P7, class P8>
182struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
183  TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7,
184  TypeList <P8> > > > > > > > >
185{
186  static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
187    TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
188    TypeList <P7, TypeList <P8> > > > > > > > > &tvl)
189  {
190    return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
191      tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
192      tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
193  }
194  static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
195    TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
196    TypeList <P7, TypeList <P8> > > > > > > > > &tvl)
197  {
198    return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
199      tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
200      tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
201  }
202};
203
204#endif
Property changes on: trunk/src/lib/lua/bridge/detail/Constructor.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/Stack.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2007, Nathan Reed
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//------------------------------------------------------------------------------
31/**
32    Receive the lua_State* as an argument.
33*/
34template <>
35struct Stack <lua_State*>
36{
37  static lua_State* get (lua_State* L, int)
38  {
39    return L;
40  }
41};
42
43//------------------------------------------------------------------------------
44/**
45    Push a lua_CFunction.
46*/
47template <>
48struct Stack <lua_CFunction>
49{
50  static void push (lua_State* L, lua_CFunction f)
51  {
52    lua_pushcfunction (L, f);
53  }
54
55  static lua_CFunction get (lua_State* L, int index)
56  {
57    return lua_tocfunction (L, index);
58  }
59};
60
61//------------------------------------------------------------------------------
62/**
63    Stack specialization for `int`.
64*/
65template <>
66struct Stack <int>
67{
68  static inline void push (lua_State* L, int value)
69  {
70    lua_pushinteger (L, static_cast <lua_Integer> (value));
71  }
72 
73  static inline int get (lua_State* L, int index)
74  {
75    return static_cast <int> (luaL_checkinteger (L, index));
76  }
77};
78
79template <>
80struct Stack <int const&>
81{
82  static inline void push (lua_State* L, int value)
83  {
84    lua_pushnumber (L, static_cast <lua_Number> (value));
85  }
86 
87  static inline int get (lua_State* L, int index)
88  {
89    return static_cast <int > (luaL_checknumber (L, index));
90  }
91};
92//------------------------------------------------------------------------------
93/**
94    Stack specialization for `unsigned int`.
95*/
96template <>
97struct Stack <unsigned int>
98{
99  static inline void push (lua_State* L, unsigned int value)
100  {
101    lua_pushinteger (L, static_cast <lua_Integer> (value));
102  }
103 
104  static inline unsigned int get (lua_State* L, int index)
105  {
106    return static_cast <unsigned int> (luaL_checkinteger (L, index));
107  }
108};
109
110template <>
111struct Stack <unsigned int const&>
112{
113  static inline void push (lua_State* L, unsigned int value)
114  {
115    lua_pushnumber (L, static_cast <lua_Number> (value));
116  }
117 
118  static inline unsigned int get (lua_State* L, int index)
119  {
120    return static_cast <unsigned int > (luaL_checknumber (L, index));
121  }
122};
123
124//------------------------------------------------------------------------------
125/**
126    Stack specialization for `unsigned char`.
127*/
128template <>
129struct Stack <unsigned char>
130{
131  static inline void push (lua_State* L, unsigned char value)
132  {
133    lua_pushinteger (L, static_cast <lua_Integer> (value));
134  }
135 
136  static inline unsigned char get (lua_State* L, int index)
137  {
138    return static_cast <unsigned char> (luaL_checkinteger (L, index));
139  }
140};
141
142template <>
143struct Stack <unsigned char const&>
144{
145  static inline void push (lua_State* L, unsigned char value)
146  {
147    lua_pushnumber (L, static_cast <lua_Number> (value));
148  }
149 
150  static inline unsigned char get (lua_State* L, int index)
151  {
152    return static_cast <unsigned char> (luaL_checknumber (L, index));
153  }
154};
155
156//------------------------------------------------------------------------------
157/**
158    Stack specialization for `short`.
159*/
160template <>
161struct Stack <short>
162{
163  static inline void push (lua_State* L, short value)
164  {
165    lua_pushinteger (L, static_cast <lua_Integer> (value));
166  }
167 
168  static inline short get (lua_State* L, int index)
169  {
170    return static_cast <short> (luaL_checkinteger (L, index));
171  }
172};
173
174template <>
175struct Stack <short const&>
176{
177  static inline void push (lua_State* L, short value)
178  {
179    lua_pushnumber (L, static_cast <lua_Number> (value));
180  }
181 
182  static inline short get (lua_State* L, int index)
183  {
184    return static_cast <short> (luaL_checknumber (L, index));
185  }
186};
187
188//------------------------------------------------------------------------------
189/**
190    Stack specialization for `unsigned short`.
191*/
192template <>
193struct Stack <unsigned short>
194{
195  static inline void push (lua_State* L, unsigned short value)
196  {
197    lua_pushinteger (L, static_cast <lua_Integer> (value));
198  }
199 
200  static inline unsigned short get (lua_State* L, int index)
201  {
202    return static_cast <unsigned short> (luaL_checkinteger (L, index));
203  }
204};
205
206template <>
207struct Stack <unsigned short const&>
208{
209  static inline void push (lua_State* L, unsigned short value)
210  {
211    lua_pushnumber (L, static_cast <lua_Number> (value));
212  }
213 
214  static inline unsigned short get (lua_State* L, int index)
215  {
216    return static_cast <unsigned short> (luaL_checknumber (L, index));
217  }
218};
219
220//------------------------------------------------------------------------------
221/**
222    Stack specialization for `long`.
223*/
224template <>
225struct Stack <long>
226{
227  static inline void push (lua_State* L, long value)
228  {
229    lua_pushinteger (L, static_cast <lua_Integer> (value));
230  }
231 
232  static inline long get (lua_State* L, int index)
233  {
234    return static_cast <long> (luaL_checkinteger (L, index));
235  }
236};
237
238template <>
239struct Stack <long const&>
240{
241  static inline void push (lua_State* L, long value)
242  {
243    lua_pushnumber (L, static_cast <lua_Number> (value));
244  }
245 
246  static inline long get (lua_State* L, int index)
247  {
248    return static_cast <long> (luaL_checknumber (L, index));
249  }
250};
251
252//------------------------------------------------------------------------------
253/**
254    Stack specialization for `unsigned long`.
255*/
256template <>
257struct Stack <unsigned long>
258{
259  static inline void push (lua_State* L, unsigned long value)
260  {
261    lua_pushinteger (L, static_cast <lua_Integer> (value));
262  }
263 
264  static inline unsigned long get (lua_State* L, int index)
265  {
266    return static_cast <unsigned long> (luaL_checkinteger (L, index));
267  }
268};
269
270template <>
271struct Stack <unsigned long const&>
272{
273  static inline void push (lua_State* L, unsigned long value)
274  {
275    lua_pushnumber (L, static_cast <lua_Number> (value));
276  }
277 
278  static inline unsigned long get (lua_State* L, int index)
279  {
280    return static_cast <unsigned long> (luaL_checknumber (L, index));
281  }
282};
283
284//------------------------------------------------------------------------------
285/**
286    Stack specialization for `float`.
287*/
288template <>
289struct Stack <float>
290{
291  static inline void push (lua_State* L, float value)
292  {
293    lua_pushnumber (L, static_cast <lua_Number> (value));
294  }
295 
296  static inline float get (lua_State* L, int index)
297  {
298    return static_cast <float> (luaL_checknumber (L, index));
299  }
300};
301
302template <>
303struct Stack <float const&>
304{
305  static inline void push (lua_State* L, float value)
306  {
307    lua_pushnumber (L, static_cast <lua_Number> (value));
308  }
309 
310  static inline float get (lua_State* L, int index)
311  {
312    return static_cast <float> (luaL_checknumber (L, index));
313  }
314};
315
316//------------------------------------------------------------------------------
317/**
318    Stack specialization for `double`.
319*/
320template <> struct Stack <double>
321{
322  static inline void push (lua_State* L, double value)
323  {
324    lua_pushnumber (L, static_cast <lua_Number> (value));
325  }
326 
327  static inline double get (lua_State* L, int index)
328  {
329    return static_cast <double> (luaL_checknumber (L, index));
330  }
331};
332
333template <> struct Stack <double const&>
334{
335  static inline void push (lua_State* L, double value)
336  {
337    lua_pushnumber (L, static_cast <lua_Number> (value));
338  }
339 
340  static inline double get (lua_State* L, int index)
341  {
342    return static_cast <double> (luaL_checknumber (L, index));
343  }
344};
345
346//------------------------------------------------------------------------------
347/**
348    Stack specialization for `bool`.
349*/
350template <>
351struct Stack <bool> {
352  static inline void push (lua_State* L, bool value)
353  {
354    lua_pushboolean (L, value ? 1 : 0);
355  }
356 
357  static inline bool get (lua_State* L, int index)
358  {
359    return lua_toboolean (L, index) ? true : false;
360  }
361};
362
363template <>
364struct Stack <bool const&> {
365  static inline void push (lua_State* L, bool value)
366  {
367    lua_pushboolean (L, value ? 1 : 0);
368  }
369 
370  static inline bool get (lua_State* L, int index)
371  {
372    return lua_toboolean (L, index) ? true : false;
373  }
374};
375
376//------------------------------------------------------------------------------
377/**
378    Stack specialization for `char`.
379*/
380template <>
381struct Stack <char>
382{
383  static inline void push (lua_State* L, char value)
384  {
385    char str [2] = { value, 0 };
386    lua_pushstring (L, str);
387  }
388 
389  static inline char get (lua_State* L, int index)
390  {
391    return luaL_checkstring (L, index) [0];
392  }
393};
394
395template <>
396struct Stack <char const&>
397{
398  static inline void push (lua_State* L, char value)
399  {
400    char str [2] = { value, 0 };
401    lua_pushstring (L, str);
402  }
403 
404  static inline char get (lua_State* L, int index)
405  {
406    return luaL_checkstring (L, index) [0];
407  }
408};
409
410//------------------------------------------------------------------------------
411/**
412    Stack specialization for `float`.
413*/
414template <>
415struct Stack <char const*>
416{
417  static inline void push (lua_State* L, char const* str)
418  {
419    if (str != 0)
420      lua_pushstring (L, str);
421    else
422      lua_pushnil (L);
423  }
424
425  static inline char const* get (lua_State* L, int index)
426  {
427    return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index);
428  }
429};
430
431//------------------------------------------------------------------------------
432/**
433    Stack specialization for `std::string`.
434*/
435template <>
436struct Stack <std::string>
437{
438  static inline void push (lua_State* L, std::string const& str)
439  {
440    lua_pushlstring (L, str.c_str (), str.size());
441  }
442
443  static inline std::string get (lua_State* L, int index)
444  {
445    size_t len;
446    const char *str = luaL_checklstring(L, index, &len);
447    return std::string (str, len);
448  }
449};
450
451//------------------------------------------------------------------------------
452/**
453    Stack specialization for `std::string const&`.
454*/
455template <>
456struct Stack <std::string const&>
457{
458  static inline void push (lua_State* L, std::string const& str)
459  {
460    lua_pushstring (L, str.c_str());
461  }
462
463  static inline std::string get (lua_State* L, int index)
464  {
465    size_t len;
466    const char *str = luaL_checklstring(L, index, &len);
467    return std::string (str, len);
468  }
469};
Property changes on: trunk/src/lib/lua/bridge/detail/Stack.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/detail/dump.h
r0r31046
1#include <sstream>
2#include <string>
3
4std::string dumpLuaState(lua_State *L) {
5   std::stringstream ostr;
6   int i;
7   int top = lua_gettop(L);
8   ostr << "top=" << top << ":\n";
9   for (i = 1; i <= top; ++i) {
10      int t = lua_type(L, i);
11      switch(t) {
12      case LUA_TSTRING:
13         ostr << "  " << i << ": '" << lua_tostring(L, i) << "'\n";
14         break;
15      case LUA_TBOOLEAN:
16         ostr << "  " << i << ": " <<
17               (lua_toboolean(L, i) ? "true" : "false") << "\n";
18         break;
19      case LUA_TNUMBER:
20         ostr << "  " << i << ": " << lua_tonumber(L, i) << "\n";
21         break;
22      default:
23         ostr << "  " << i << ": TYPE=" << lua_typename(L, t) << "\n";
24         break;
25      }
26   }
27   return ostr.str();
28}
Property changes on: trunk/src/lib/lua/bridge/detail/dump.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lua/bridge/LuaBridge.h
r0r31046
1//------------------------------------------------------------------------------
2/*
3  https://github.com/vinniefalco/LuaBridge
4 
5  Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6  Copyright 2007, Nathan Reed
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#ifndef LUABRIDGE_LUABRIDGE_HEADER
31#define LUABRIDGE_LUABRIDGE_HEADER
32
33// All #include dependencies are listed here
34// instead of in the individual header files.
35//
36#include <cassert>
37#include <sstream>
38#include <stdexcept>
39#include <string>
40#include <typeinfo>
41
42#define LUABRIDGE_MAJOR_VERSION 2
43#define LUABRIDGE_MINOR_VERSION 0
44#define LUABRIDGE_VERSION 200
45
46namespace luabridge
47{
48
49// Forward declaration
50//
51template <class T>
52struct Stack;
53
54#include "detail/LuaHelpers.h"
55
56#include "detail/TypeTraits.h"
57#include "detail/TypeList.h"
58#include "detail/FuncTraits.h"
59#include "detail/Constructor.h"
60#include "detail/Stack.h"
61#include "detail/ClassInfo.h"
62
63class LuaRef;
64
65#include "detail/LuaException.h"
66#include "detail/LuaRef.h"
67#include "detail/Iterator.h"
68
69//------------------------------------------------------------------------------
70/**
71    security options.
72*/
73class Security
74{
75public:
76  static bool hideMetatables ()
77  {
78    return getSettings().hideMetatables;
79  }
80
81  static void setHideMetatables (bool shouldHide)
82  {
83    getSettings().hideMetatables = shouldHide;
84  }
85
86private:
87  struct Settings
88  {
89    Settings () : hideMetatables (true)
90    {
91    }
92
93    bool hideMetatables;
94  };
95
96  static Settings& getSettings ()
97  {
98    static Settings settings;
99    return settings;
100  }
101};
102
103#include "detail/Userdata.h"
104#include "detail/CFunctions.h"
105#include "detail/Namespace.h"
106
107//------------------------------------------------------------------------------
108/**
109    Push an object onto the Lua stack.
110*/
111template <class T>
112inline void push (lua_State* L, T t)
113{
114  Stack <T>::push (L, t);
115}
116
117//------------------------------------------------------------------------------
118/**
119  Set a global value in the lua_State.
120
121  @note This works on any type specialized by `Stack`, including `LuaRef` and
122        its table proxies.
123*/
124template <class T>
125inline void setGlobal (lua_State* L, T t, char const* name)
126{
127  push (L, t);
128  lua_setglobal (L, name);
129}
130
131//------------------------------------------------------------------------------
132/**
133  Change whether or not metatables are hidden (on by default).
134*/
135inline void setHideMetatables (bool shouldHide)
136{
137  Security::setHideMetatables (shouldHide);
138}
139
140}
141
142#endif
Property changes on: trunk/src/lib/lua/bridge/LuaBridge.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Previous 199869 Revisions Next


© 1997-2024 The MAME Team