functions.hpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* Luwra
  2. * Minimal-overhead Lua wrapper for C++
  3. *
  4. * Copyright (C) 2015, Ole Krüger <ole@vprsm.de>
  5. */
  6. #ifndef LUWRA_FUNCTIONS_H_
  7. #define LUWRA_FUNCTIONS_H_
  8. #include "common.hpp"
  9. #include "types.hpp"
  10. #include "stack.hpp"
  11. LUWRA_NS_BEGIN
  12. namespace internal {
  13. template <typename T>
  14. struct FunctionWrapper {
  15. static_assert(
  16. sizeof(T) == -1,
  17. "Parameter to FunctionWrapper is not a valid signature"
  18. );
  19. };
  20. template <typename R, typename... A>
  21. struct FunctionWrapper<R(A...)> {
  22. template <R (* fun)(A...)> static inline
  23. int invoke(State* state) {
  24. return map<R(A...)>(state, fun);
  25. }
  26. };
  27. // We need an alias, because function pointers are weird
  28. template <typename R, typename... A>
  29. struct FunctionWrapper<R(*)(A...)>: FunctionWrapper<R(A...)> {};
  30. }
  31. template <typename S>
  32. struct NativeFunction {
  33. static_assert(
  34. sizeof(S) == -1,
  35. "Parameter to NativeFunction is not a valid signature"
  36. );
  37. };
  38. /**
  39. * A callable native Lua function.
  40. * \note This value is only available as long as it exists on the stack.
  41. */
  42. template <typename R, typename... A>
  43. struct NativeFunction<R(A...)> {
  44. State* state;
  45. int index;
  46. inline
  47. R operator ()(A&&... args) {
  48. lua_pushvalue(state, index);
  49. size_t numArgs = push(state, std::forward<A>(args)...);
  50. lua_call(state, numArgs, 1);
  51. R returnValue = read<R>(state, -1);
  52. lua_pop(state, 1);
  53. return returnValue;
  54. }
  55. };
  56. /**
  57. * A callable native Lua function.
  58. * \note This value is only available as long as it exists on the stack.
  59. */
  60. template <typename... A>
  61. struct NativeFunction<void(A...)> {
  62. State* state;
  63. int index;
  64. inline
  65. void operator ()(A&&... args) {
  66. lua_pushvalue(state, index);
  67. size_t numArgs = push(state, std::forward<A>(args)...);
  68. lua_call(state, numArgs, 0);
  69. }
  70. };
  71. template <typename R, typename... A>
  72. struct Value<NativeFunction<R(A...)>> {
  73. static inline
  74. NativeFunction<R(A...)> read(State* state, int index) {
  75. luaL_checktype(state, index, LUA_TFUNCTION);
  76. return {state, index};
  77. }
  78. };
  79. LUWRA_NS_END
  80. /**
  81. * Generate a `lua_CFunction` wrapper for a function.
  82. * \param fun Fully qualified function name (Do not supply a pointer)
  83. * \returns Wrapped function as `lua_CFunction`
  84. */
  85. #define LUWRA_WRAP_FUNCTION(fun) \
  86. (&luwra::internal::FunctionWrapper<decltype(&fun)>::template invoke<&fun>)
  87. #endif