functions.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 static_cast<int>(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. /**
  32. * A callable native Lua function.
  33. * \note This value is only available as long as it exists on the stack.
  34. */
  35. template <typename R>
  36. struct NativeFunction: Reference {
  37. NativeFunction(State* state, int index):
  38. Reference(state, index)
  39. {}
  40. template <typename... A> inline
  41. R operator ()(A&&... args) {
  42. impl->push();
  43. size_t numArgs = push(impl->state, std::forward<A>(args)...);
  44. lua_call(impl->state, static_cast<int>(numArgs), 1);
  45. R returnValue = Value<R>::read(impl->state, -1);
  46. lua_pop(impl->state, 1);
  47. return returnValue;
  48. }
  49. };
  50. /**
  51. * A callable native Lua function.
  52. * \note This value is only available as long as it exists on the stack.
  53. */
  54. template <>
  55. struct NativeFunction<void>: Reference {
  56. NativeFunction(State* state, int index):
  57. Reference(state, index)
  58. {}
  59. template <typename... A> inline
  60. void operator ()(A&&... args) {
  61. impl->push();
  62. size_t numArgs = push(impl->state, std::forward<A>(args)...);
  63. lua_call(impl->state, static_cast<int>(numArgs), 0);
  64. }
  65. };
  66. template <typename R>
  67. struct Value<NativeFunction<R>> {
  68. static inline
  69. NativeFunction<R> read(State* state, int index) {
  70. luaL_checktype(state, index, LUA_TFUNCTION);
  71. return NativeFunction<R>(state, index);
  72. }
  73. };
  74. LUWRA_NS_END
  75. /**
  76. * Generate a `lua_CFunction` wrapper for a function.
  77. * \param fun Fully qualified function name (Do not supply a pointer)
  78. * \returns Wrapped function as `lua_CFunction`
  79. */
  80. #define LUWRA_WRAP_FUNCTION(fun) \
  81. (&luwra::internal::FunctionWrapper<decltype(&fun)>::template invoke<&fun>)
  82. #endif