?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. // https://github.com/vinniefalco/LuaBridge
  2. // Copyright 2020, Dmitry Tarakanov
  3. // Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
  4. // SPDX-License-Identifier: MIT
  5.  
  6. #pragma once
  7.  
  8. #include <LuaBridge/detail/Config.h>
  9. #include <LuaBridge/detail/TypeList.h>
  10.  
  11. #include <functional>
  12.  
  13. namespace luabridge {
  14.  
  15. namespace detail {
  16.  
  17. /**
  18.   Since the throw specification is part of a function signature, the FuncTraits
  19.   family of templates needs to be specialized for both types. The
  20.   LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or
  21.   'noexcept' (if C++11 is available) to distinguish the functions.
  22. */
  23. #if defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__clang__) || defined(__GNUC__) || \
  24.     (defined(_MSC_VER) && (_MSC_VER >= 1700))
  25. // Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc  compilers do not
  26. // distinguish the throw specification in the function signature.
  27. #define LUABRIDGE_THROWSPEC
  28. #else
  29. // Visual Studio 10 and earlier pay too much mind to useless throw () spec.
  30. //
  31. #define LUABRIDGE_THROWSPEC throw()
  32. #endif
  33.  
  34. //==============================================================================
  35. /**
  36.  * Traits class for unrolling the type list values into function arguments.
  37.  */
  38. template<class ReturnType, size_t NUM_PARAMS>
  39. struct Caller;
  40.  
  41. template<class ReturnType>
  42. struct Caller<ReturnType, 0>
  43. {
  44.     template<class Fn, class Params>
  45.     static ReturnType f(Fn& fn, TypeListValues<Params>&)
  46.     {
  47.         return fn();
  48.     }
  49.  
  50.     template<class T, class MemFn, class Params>
  51.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>&)
  52.     {
  53.         return (obj->*fn)();
  54.     }
  55. };
  56.  
  57. template<class ReturnType>
  58. struct Caller<ReturnType, 1>
  59. {
  60.     template<class Fn, class Params>
  61.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  62.     {
  63.         return fn(tvl.hd);
  64.     }
  65.  
  66.     template<class T, class MemFn, class Params>
  67.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  68.     {
  69.         return (obj->*fn)(tvl.hd);
  70.     }
  71. };
  72.  
  73. template<class ReturnType>
  74. struct Caller<ReturnType, 2>
  75. {
  76.     template<class Fn, class Params>
  77.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  78.     {
  79.         return fn(tvl.hd, tvl.tl.hd);
  80.     }
  81.  
  82.     template<class T, class MemFn, class Params>
  83.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  84.     {
  85.         return (obj->*fn)(tvl.hd, tvl.tl.hd);
  86.     }
  87. };
  88.  
  89. template<class ReturnType>
  90. struct Caller<ReturnType, 3>
  91. {
  92.     template<class Fn, class Params>
  93.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  94.     {
  95.         return fn(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
  96.     }
  97.  
  98.     template<class T, class MemFn, class Params>
  99.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  100.     {
  101.         return (obj->*fn)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
  102.     }
  103. };
  104.  
  105. template<class ReturnType>
  106. struct Caller<ReturnType, 4>
  107. {
  108.     template<class Fn, class Params>
  109.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  110.     {
  111.         return fn(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
  112.     }
  113.  
  114.     template<class T, class MemFn, class Params>
  115.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  116.     {
  117.         return (obj->*fn)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
  118.     }
  119. };
  120.  
  121. template<class ReturnType>
  122. struct Caller<ReturnType, 5>
  123. {
  124.     template<class Fn, class Params>
  125.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  126.     {
  127.         return fn(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
  128.     }
  129.  
  130.     template<class T, class MemFn, class Params>
  131.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  132.     {
  133.         return (obj->*fn)(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
  134.     }
  135. };
  136.  
  137. template<class ReturnType>
  138. struct Caller<ReturnType, 6>
  139. {
  140.     template<class Fn, class Params>
  141.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  142.     {
  143.         return fn(tvl.hd,
  144.                   tvl.tl.hd,
  145.                   tvl.tl.tl.hd,
  146.                   tvl.tl.tl.tl.hd,
  147.                   tvl.tl.tl.tl.tl.hd,
  148.                   tvl.tl.tl.tl.tl.tl.hd);
  149.     }
  150.  
  151.     template<class T, class MemFn, class Params>
  152.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  153.     {
  154.         return (obj->*fn)(tvl.hd,
  155.                           tvl.tl.hd,
  156.                           tvl.tl.tl.hd,
  157.                           tvl.tl.tl.tl.hd,
  158.                           tvl.tl.tl.tl.tl.hd,
  159.                           tvl.tl.tl.tl.tl.tl.hd);
  160.     }
  161. };
  162.  
  163. template<class ReturnType>
  164. struct Caller<ReturnType, 7>
  165. {
  166.     template<class Fn, class Params>
  167.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  168.     {
  169.         return fn(tvl.hd,
  170.                   tvl.tl.hd,
  171.                   tvl.tl.tl.hd,
  172.                   tvl.tl.tl.tl.hd,
  173.                   tvl.tl.tl.tl.tl.hd,
  174.                   tvl.tl.tl.tl.tl.tl.hd,
  175.                   tvl.tl.tl.tl.tl.tl.tl.hd);
  176.     }
  177.  
  178.     template<class T, class MemFn, class Params>
  179.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  180.     {
  181.         return (obj->*fn)(tvl.hd,
  182.                           tvl.tl.hd,
  183.                           tvl.tl.tl.hd,
  184.                           tvl.tl.tl.tl.hd,
  185.                           tvl.tl.tl.tl.tl.hd,
  186.                           tvl.tl.tl.tl.tl.tl.hd,
  187.                           tvl.tl.tl.tl.tl.tl.tl.hd);
  188.     }
  189. };
  190.  
  191. template<class ReturnType>
  192. struct Caller<ReturnType, 8>
  193. {
  194.     template<class Fn, class Params>
  195.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  196.     {
  197.         return fn(tvl.hd,
  198.                   tvl.tl.hd,
  199.                   tvl.tl.tl.hd,
  200.                   tvl.tl.tl.tl.hd,
  201.                   tvl.tl.tl.tl.tl.hd,
  202.                   tvl.tl.tl.tl.tl.tl.hd,
  203.                   tvl.tl.tl.tl.tl.tl.tl.hd,
  204.                   tvl.tl.tl.tl.tl.tl.tl.tl.hd);
  205.     }
  206.  
  207.     template<class T, class MemFn, class Params>
  208.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  209.     {
  210.         return (obj->*fn)(tvl.hd,
  211.                           tvl.tl.hd,
  212.                           tvl.tl.tl.hd,
  213.                           tvl.tl.tl.tl.hd,
  214.                           tvl.tl.tl.tl.tl.hd,
  215.                           tvl.tl.tl.tl.tl.tl.hd,
  216.                           tvl.tl.tl.tl.tl.tl.tl.hd,
  217.                           tvl.tl.tl.tl.tl.tl.tl.tl.hd);
  218.     }
  219. };
  220.  
  221. template<class ReturnType>
  222. struct Caller<ReturnType, 9>
  223. {
  224.     template<class Fn, class Params>
  225.     static ReturnType f(Fn& fn, TypeListValues<Params>& tvl)
  226.     {
  227.         return fn(tvl.hd,
  228.                   tvl.tl.hd,
  229.                   tvl.tl.tl.hd,
  230.                   tvl.tl.tl.tl.hd,
  231.                   tvl.tl.tl.tl.tl.hd,
  232.                   tvl.tl.tl.tl.tl.tl.hd,
  233.                   tvl.tl.tl.tl.tl.tl.tl.hd,
  234.                   tvl.tl.tl.tl.tl.tl.tl.tl.hd,
  235.                   tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd);
  236.     }
  237.  
  238.     template<class T, class MemFn, class Params>
  239.     static ReturnType f(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  240.     {
  241.         return (obj->*fn)(tvl.hd,
  242.                           tvl.tl.hd,
  243.                           tvl.tl.tl.hd,
  244.                           tvl.tl.tl.tl.hd,
  245.                           tvl.tl.tl.tl.tl.hd,
  246.                           tvl.tl.tl.tl.tl.tl.hd,
  247.                           tvl.tl.tl.tl.tl.tl.tl.hd,
  248.                           tvl.tl.tl.tl.tl.tl.tl.tl.hd,
  249.                           tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd);
  250.     }
  251. };
  252.  
  253. template<class ReturnType, class Fn, class Params>
  254. ReturnType doCall(Fn& fn, TypeListValues<Params>& tvl)
  255. {
  256.     return Caller<ReturnType, TypeListSize<Params>::value>::f(fn, tvl);
  257. }
  258.  
  259. template<class ReturnType, class T, class MemFn, class Params>
  260. ReturnType doCall(T* obj, MemFn& fn, TypeListValues<Params>& tvl)
  261. {
  262.     return Caller<ReturnType, TypeListSize<Params>::value>::f(obj, fn, tvl);
  263. }
  264.  
  265. //==============================================================================
  266. /**
  267.     Traits for function pointers.
  268.  
  269.     There are three types of functions: global, non-const member, and const
  270.     member. These templates determine the type of function, which class type it
  271.     belongs to if it is a class member, the const-ness if it is a member
  272.     function, and the type information for the return value and argument list.
  273.  
  274.     Expansions are provided for functions with up to 8 parameters. This can be
  275.     manually extended, or expanded to an arbitrary amount using C++11 features.
  276. */
  277. template<class MemFn, class D = MemFn>
  278. struct FuncTraits
  279. {
  280. };
  281.  
  282. /* Ordinary function pointers. */
  283.  
  284. template<class R, class... ParamList>
  285. struct FuncTraits<R (*)(ParamList...)>
  286. {
  287.     static bool const isMemberFunction = false;
  288.     using DeclType = R (*)(ParamList...);
  289.     using ReturnType = R;
  290.     using Params = typename MakeTypeList<ParamList...>::Result;
  291.  
  292.     static R call(const DeclType& fp, TypeListValues<Params>& tvl) { return doCall<R>(fp, tvl); }
  293. };
  294.  
  295. /* Windows: WINAPI (a.k.a. __stdcall) function pointers. */
  296.  
  297. #ifdef _M_IX86 // Windows 32bit only
  298.  
  299. template<class R, class... ParamList>
  300. struct FuncTraits<R(__stdcall*)(ParamList...)>
  301. {
  302.     static bool const isMemberFunction = false;
  303.     using DeclType = R(__stdcall*)(ParamList...);
  304.     using ReturnType = R;
  305.     using Params = typename MakeTypeList<ParamList...>::Result;
  306.  
  307.     static R call(const DeclType& fp, TypeListValues<Params>& tvl) { return doCall<R>(fp, tvl); }
  308. };
  309.  
  310. #endif // _M_IX86
  311.  
  312. /* Non-const member function pointers. */
  313.  
  314. template<class T, class R, class... ParamList>
  315. struct FuncTraits<R (T::*)(ParamList...)>
  316. {
  317.     static bool const isMemberFunction = true;
  318.     static bool const isConstMemberFunction = false;
  319.     using DeclType = R (T::*)(ParamList...);
  320.     using ClassType = T;
  321.     using ReturnType = R;
  322.     using Params = typename MakeTypeList<ParamList...>::Result;
  323.  
  324.     static R call(ClassType* obj, const DeclType& fp, TypeListValues<Params>& tvl)
  325.     {
  326.         return doCall<R>(obj, fp, tvl);
  327.     }
  328. };
  329.  
  330. /* Const member function pointers. */
  331.  
  332. template<class T, class R, class... ParamList>
  333. struct FuncTraits<R (T::*)(ParamList...) const>
  334. {
  335.     static bool const isMemberFunction = true;
  336.     static bool const isConstMemberFunction = true;
  337.     using DeclType = R (T::*)(ParamList...) const;
  338.     using ClassType = T;
  339.     using ReturnType = R;
  340.     using Params = typename MakeTypeList<ParamList...>::Result;
  341.  
  342.     static R call(const ClassType* obj, const DeclType& fp, TypeListValues<Params>& tvl)
  343.     {
  344.         return doCall<R>(obj, fp, tvl);
  345.     }
  346. };
  347.  
  348. /* std::function */
  349.  
  350. template<class R, class... ParamList>
  351. struct FuncTraits<std::function<R(ParamList...)>>
  352. {
  353.     static bool const isMemberFunction = false;
  354.     static bool const isConstMemberFunction = false;
  355.     using DeclType = std::function<R(ParamList...)>;
  356.     using ReturnType = R;
  357.     using Params = typename MakeTypeList<ParamList...>::Result;
  358.  
  359.     static ReturnType call(DeclType& fn, TypeListValues<Params>& tvl)
  360.     {
  361.         return doCall<ReturnType>(fn, tvl);
  362.     }
  363. };
  364.  
  365. template<class ReturnType, class Params, int startParam>
  366. struct Invoke
  367. {
  368.     template<class Fn>
  369.     static int run(lua_State* L, Fn& fn)
  370.     {
  371.         try
  372.         {
  373.             ArgList<Params, startParam> args(L);
  374.             Stack<ReturnType>::push(L, FuncTraits<Fn>::call(fn, args));
  375.             return 1;
  376.         }
  377.         catch (const std::exception& e)
  378.         {
  379.             return luaL_error(L, e.what());
  380.         }
  381.     }
  382.  
  383.     template<class T, class MemFn>
  384.     static int run(lua_State* L, T* object, const MemFn& fn)
  385.     {
  386.         try
  387.         {
  388.             ArgList<Params, startParam> args(L);
  389.             Stack<ReturnType>::push(L, FuncTraits<MemFn>::call(object, fn, args));
  390.             return 1;
  391.         }
  392.         catch (const std::exception& e)
  393.         {
  394.             return luaL_error(L, e.what());
  395.         }
  396.     }
  397. };
  398.  
  399. template<class Params, int startParam>
  400. struct Invoke<void, Params, startParam>
  401. {
  402.     template<class Fn>
  403.     static int run(lua_State* L, Fn& fn)
  404.     {
  405.         try
  406.         {
  407.             ArgList<Params, startParam> args(L);
  408.             FuncTraits<Fn>::call(fn, args);
  409.             return 0;
  410.         }
  411.         catch (const std::exception& e)
  412.         {
  413.             return luaL_error(L, e.what());
  414.         }
  415.     }
  416.  
  417.     template<class T, class MemFn>
  418.     static int run(lua_State* L, T* object, const MemFn& fn)
  419.     {
  420.         try
  421.         {
  422.             ArgList<Params, startParam> args(L);
  423.             FuncTraits<MemFn>::call(object, fn, args);
  424.             return 0;
  425.         }
  426.         catch (const std::exception& e)
  427.         {
  428.             return luaL_error(L, e.what());
  429.         }
  430.     }
  431. };
  432.  
  433. } // namespace detail
  434.  
  435. } // namespace luabridge
  436.