methods.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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 map<FunctionSignature>(state, hook<meth>);
  35. }
  36. };
  37. // 'const'-qualified methods
  38. template <typename T, typename R, typename... A>
  39. struct MethodWrapper<R (T::*)(A...) const> {
  40. using MethodPointerType = R (T::*)(A...) const;
  41. using FunctionSignature = R (const T*, A...);
  42. template <MethodPointerType meth> static inline
  43. R hook(const T* parent, A... args) {
  44. return (parent->*meth)(std::forward<A>(args)...);
  45. }
  46. template <MethodPointerType meth> static inline
  47. int invoke(State* state) {
  48. return map<FunctionSignature>(state, hook<meth>);
  49. }
  50. };
  51. // 'volatile'-qualified methods
  52. template <typename T, typename R, typename... A>
  53. struct MethodWrapper<R (T::*)(A...) volatile> {
  54. using MethodPointerType = R (T::*)(A...) volatile;
  55. using FunctionSignature = R (volatile T*, A...);
  56. template <MethodPointerType meth> static inline
  57. R hook(volatile T* parent, A... args) {
  58. return (parent->*meth)(std::forward<A>(args)...);
  59. }
  60. template <MethodPointerType meth> static inline
  61. int invoke(State* state) {
  62. return map<FunctionSignature>(state, hook<meth>);
  63. }
  64. };
  65. // unqualified methods
  66. template <typename T, typename R, typename... A>
  67. struct MethodWrapper<R (T::*)(A...)> {
  68. using MethodPointerType = R (T::*)(A...);
  69. using FunctionSignature = R (T*, A...);
  70. template <MethodPointerType meth> static inline
  71. R hook(T* parent, A... args) {
  72. return (parent->*meth)(std::forward<A>(args)...);
  73. }
  74. template <MethodPointerType meth> static inline
  75. int invoke(State* state) {
  76. return map<FunctionSignature>(state, hook<meth>);
  77. }
  78. };
  79. }
  80. LUWRA_NS_END
  81. /**
  82. * Generate a `lua_CFunction` wrapper for a method.
  83. * \param meth Fully qualified method name (Do not supply a pointer)
  84. * \return Wrapped function as `lua_CFunction`
  85. */
  86. #define LUWRA_WRAP_METHOD(meth) \
  87. (&luwra::internal::MethodWrapper<decltype(&meth)>::template invoke<&meth>)
  88. #endif