functions.hpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 function signature"
  18. );
  19. };
  20. template <>
  21. struct FunctionWrapper<void()> {
  22. template <void(*function_pointer)()> static inline
  23. int invoke(State*) {
  24. function_pointer();
  25. return 0;
  26. }
  27. };
  28. template <typename R>
  29. struct FunctionWrapper<R()> {
  30. template <R(*function_pointer)()> static inline
  31. int invoke(State* state) {
  32. return push(state, function_pointer());
  33. }
  34. };
  35. template <typename... A>
  36. struct FunctionWrapper<void(A...)> {
  37. template <void (*function_pointer)(A...)> static inline
  38. int invoke(State* state) {
  39. apply(state, function_pointer);
  40. return 0;
  41. }
  42. };
  43. template <typename R, typename... A>
  44. struct FunctionWrapper<R(A...)> {
  45. template <R (*function_pointer)(A...)> static inline
  46. int invoke(State* state) {
  47. return push(
  48. state,
  49. apply(state, function_pointer)
  50. );
  51. }
  52. };
  53. }
  54. /**
  55. * Assuming its parameters can be retrieved from the Lua stack, ordinary functions can be wrapped
  56. * using the `wrap_function` instance in order to produce a C function which can be used by the
  57. * Lua VM.
  58. *
  59. * Assuming your function has the following signature:
  60. *
  61. * R my_fun(A0, A1 ... An);
  62. *
  63. * Generate a Lua-compatible like so:
  64. *
  65. * CFunction wrapped_fun = wrap_function<R(A0, A1 ... An), my_fun>;
  66. */
  67. template <
  68. typename S,
  69. S* function_pointer
  70. >
  71. constexpr CFunction wrap_function =
  72. &internal::FunctionWrapper<S>::template invoke<function_pointer>;
  73. LUWRA_NS_END
  74. #endif