methods.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* Luwra
  2. * Minimal-overhead Lua wrapper for C++
  3. *
  4. * Copyright (C) 2015, Ole Krüger <ole@vprsm.de>
  5. */
  6. #ifndef LUWRA_METHODS_H_
  7. #define LUWRA_METHODS_H_
  8. #include "common.hpp"
  9. #include "stack.hpp"
  10. #include "functions.hpp"
  11. LUWRA_NS_BEGIN
  12. namespace internal {
  13. /**
  14. * Helper struct for wrapping user type methods
  15. */
  16. template <typename T>
  17. struct MethodWrapper {
  18. static_assert(
  19. sizeof(T) == -1,
  20. "Undefined template MethodWrapper"
  21. );
  22. };
  23. // 'const volatile'-qualified methods
  24. template <typename T, typename R, typename... A>
  25. struct MethodWrapper<R (T::*)(A...) const volatile> {
  26. using MethodPointerType = R (T::*)(A...) const volatile;
  27. using FunctionSignature = R (const volatile T*, A...);
  28. template <MethodPointerType meth> static inline
  29. R hook(const volatile T* parent, A&&... args) {
  30. return (parent->*meth)(std::forward<A>(args)...);
  31. }
  32. template <MethodPointerType meth> static inline
  33. int invoke(State* state) {
  34. return static_cast<int>(
  35. map<FunctionSignature>(state, hook<meth>)
  36. );
  37. }
  38. };
  39. // 'const'-qualified methods
  40. template <typename T, typename R, typename... A>
  41. struct MethodWrapper<R (T::*)(A...) const> {
  42. using MethodPointerType = R (T::*)(A...) const;
  43. using FunctionSignature = R (const T*, A...);
  44. template <MethodPointerType meth> static inline
  45. R hook(const T* parent, A... args) {
  46. return (parent->*meth)(std::forward<A>(args)...);
  47. }
  48. template <MethodPointerType meth> static inline
  49. int invoke(State* state) {
  50. return static_cast<int>(
  51. map<FunctionSignature>(state, hook<meth>)
  52. );
  53. }
  54. };
  55. // 'volatile'-qualified methods
  56. template <typename T, typename R, typename... A>
  57. struct MethodWrapper<R (T::*)(A...) volatile> {
  58. using MethodPointerType = R (T::*)(A...) volatile;
  59. using FunctionSignature = R (volatile T*, A...);
  60. template <MethodPointerType meth> static inline
  61. R hook(volatile T* parent, A... args) {
  62. return (parent->*meth)(std::forward<A>(args)...);
  63. }
  64. template <MethodPointerType meth> static inline
  65. int invoke(State* state) {
  66. return static_cast<int>(
  67. map<FunctionSignature>(state, hook<meth>)
  68. );
  69. }
  70. };
  71. // unqualified methods
  72. template <typename T, typename R, typename... A>
  73. struct MethodWrapper<R (T::*)(A...)> {
  74. using MethodPointerType = R (T::*)(A...);
  75. using FunctionSignature = R (T*, A...);
  76. template <MethodPointerType meth> static inline
  77. R hook(T* parent, A... args) {
  78. return (parent->*meth)(std::forward<A>(args)...);
  79. }
  80. template <MethodPointerType meth> static inline
  81. int invoke(State* state) {
  82. return static_cast<int>(
  83. map<FunctionSignature>(state, hook<meth>)
  84. );
  85. }
  86. };
  87. }
  88. LUWRA_NS_END
  89. /**
  90. * Generate a `lua_CFunction` wrapper for a method.
  91. * \param meth Fully qualified method name (Do not supply a pointer)
  92. * \return Wrapped function as `lua_CFunction`
  93. */
  94. #define LUWRA_WRAP_METHOD(meth) \
  95. (&luwra::internal::MethodWrapper<decltype(&meth)>::template invoke<&meth>)
  96. #endif