make_function.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright Daniel Wallin 2008. Use, modification and distribution is
  2. // subject to the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef LUABIND_MAKE_FUNCTION_081014_HPP
  5. # define LUABIND_MAKE_FUNCTION_081014_HPP
  6. # include <luabind/config.hpp>
  7. # include <luabind/object.hpp>
  8. # include <luabind/vector.hpp>
  9. # include <luabind/detail/call.hpp>
  10. # include <luabind/detail/deduce_signature.hpp>
  11. # include <luabind/detail/format_signature.hpp>
  12. namespace luabind {
  13. namespace detail
  14. {
  15. # ifndef LUABIND_NO_EXCEPTIONS
  16. LUABIND_API void handle_exception_aux(lua_State* L);
  17. # endif
  18. // MSVC complains about member being sensitive to alignment (C4121)
  19. // when F is a pointer to member of a class with virtual bases.
  20. # ifdef BOOST_MSVC
  21. # pragma pack(push)
  22. # pragma pack(16)
  23. # endif
  24. template <class F, class Signature, class Policies>
  25. struct function_object_impl : function_object
  26. {
  27. function_object_impl(F f, Policies const& policies)
  28. : function_object(&entry_point)
  29. , f(f)
  30. , policies(policies)
  31. {}
  32. int call(lua_State* L, invoke_context& ctx) const
  33. {
  34. return invoke(L, *this, ctx, f, Signature(), policies);
  35. }
  36. void format_signature(lua_State* L, char const* function) const
  37. {
  38. detail::format_signature(L, function, Signature());
  39. }
  40. static int entry_point(lua_State* L)
  41. {
  42. function_object_impl const* impl =
  43. *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1));
  44. invoke_context ctx;
  45. int results = 0;
  46. # ifndef LUABIND_NO_EXCEPTIONS
  47. bool exception_caught = false;
  48. try
  49. {
  50. results = invoke(
  51. L, *impl, ctx, impl->f, Signature(), impl->policies);
  52. }
  53. catch (...)
  54. {
  55. exception_caught = true;
  56. handle_exception_aux(L);
  57. }
  58. if (exception_caught)
  59. lua_error(L);
  60. # else
  61. results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies);
  62. # endif
  63. if (!ctx)
  64. {
  65. ctx.format_error(L, impl);
  66. lua_error(L);
  67. }
  68. return results;
  69. }
  70. F f;
  71. Policies policies;
  72. };
  73. # ifdef BOOST_MSVC
  74. # pragma pack(pop)
  75. # endif
  76. LUABIND_API object make_function_aux(
  77. lua_State* L, function_object* impl
  78. );
  79. LUABIND_API void add_overload(object const&, char const*, object const&);
  80. } // namespace detail
  81. template <class F, class Signature, class Policies>
  82. object make_function(lua_State* L, F f, Signature, Policies)
  83. {
  84. typedef typename detail::as_vector<Signature>::type signature;
  85. return detail::make_function_aux(
  86. L
  87. , new detail::function_object_impl<F, signature, Policies>(
  88. f, Policies()
  89. )
  90. );
  91. }
  92. template <class F>
  93. object make_function(lua_State* L, F f)
  94. {
  95. return make_function(L, detail::deduce_signature(f), detail::null_type());
  96. }
  97. } // namespace luabind
  98. #endif // LUABIND_MAKE_FUNCTION_081014_HPP