├── .gitignore ├── doc ├── git_version.in ├── examples │ ├── raw_function.cpp │ ├── basic-create_table.cpp │ ├── basic-push-to.cpp │ └── basic-class.cpp ├── CMakeLists.txt ├── index.rst ├── building.rst ├── sugar.rst ├── basic-usage.rst ├── converter-basics.rst └── Makefile ├── .travis.yml ├── LICENSE-template.txt ├── get-deps.sh ├── include └── apollo │ ├── detail │ ├── lua_state.hpp │ ├── variadic_pass.hpp │ ├── clang_stdlib_config.hpp │ ├── light_key.hpp │ ├── integer_seq.hpp │ ├── meta_util.hpp │ ├── smart_ptr.hpp │ ├── ref_binder.hpp │ ├── signature.hpp │ ├── instance_holder.hpp │ └── class_info.hpp │ ├── typeid.hpp │ ├── ctor_wrapper.hpp │ ├── stack_balance.hpp │ ├── closing_lstate.hpp │ ├── lapi.hpp │ ├── emplace_ctor.hpp │ ├── lua_include.hpp │ ├── config.hpp │ ├── gc.hpp │ ├── operator.hpp │ ├── default_argument.hpp │ ├── implicit_ctor.hpp │ ├── raw_function.hpp │ ├── error.hpp │ ├── converters_fwd.hpp │ ├── reference.hpp │ ├── property.hpp │ ├── to_raw_function.hpp │ ├── create_class.hpp │ ├── function.hpp │ ├── overload.hpp │ ├── create_table.hpp │ ├── wstring.hpp │ ├── function_primitives.hpp │ └── ward_ptr.hpp ├── test ├── testutil.hpp ├── test_suffix.hpp ├── test_prefix.hpp ├── test_ward_ptr.cpp ├── test_call_by_ref.cpp ├── CMakeLists.txt ├── test_wstring.cpp ├── testutil.cpp ├── test_typeid.cpp ├── test_create_class.cpp ├── test_property.cpp ├── test_create_table.cpp ├── test_implicit_ctor.cpp ├── benchmark.cpp ├── test_lua_utils.cpp ├── test_default_argument.cpp ├── test_reference.cpp └── test_simple_converters.cpp ├── src ├── builtin_types.cpp ├── error.cpp ├── function.cpp ├── stack_balance.cpp ├── typeid.cpp ├── lua51compat.cpp ├── class.cpp ├── CMakeLists.txt ├── reference.cpp ├── wstring.cpp ├── lapi.cpp ├── overload.cpp └── class_info.cpp ├── LICENSE.txt ├── cmake └── Modules │ └── FindApollo.cmake ├── README.md └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | _build/ 3 | .kdev4/ 4 | *.kdev4 5 | .directory 6 | -------------------------------------------------------------------------------- /doc/git_version.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Oberon00/apollo/HEAD/doc/git_version.in -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: clang 3 | env: CTEST_OUTPUT_ON_FAILURE=1 4 | install: ./get-deps.sh 5 | script: cmake . && make && make test 6 | -------------------------------------------------------------------------------- /LICENSE-template.txt: -------------------------------------------------------------------------------- 1 | Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | This file is subject to the terms of the BSD 2-Clause License. 3 | See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | -------------------------------------------------------------------------------- /get-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -ex 3 | 4 | wget http://kent.dl.sourceforge.net/project/boost/boost/1.56.0/boost_1_56_0.tar.bz2 5 | tar -xjf boost_1_56_0.tar.bz2 6 | cd boost_1_56_0 7 | ./bootstrap.sh 8 | sudo ./b2 install --with-test -d0 9 | 10 | sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y 11 | sudo apt-get update -qq -y 12 | sudo apt-get install -q -y liblua5.2-dev libstdc++-4.8-dev 13 | -------------------------------------------------------------------------------- /include/apollo/detail/lua_state.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_LUA_STATE_HPP_INCLUDED 6 | #define APOLLO_LUA_STATE_HPP_INCLUDED APOLLO_LUA_STATE_HPP_INCLUDED 7 | 8 | extern "C" struct lua_State; 9 | 10 | #endif // APOLLO_LUA_STATE_HPP_INCLUDED 11 | -------------------------------------------------------------------------------- /test/testutil.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | 7 | struct lstate_fixture { 8 | lua_State* L; 9 | 10 | lstate_fixture(); 11 | ~lstate_fixture(); 12 | }; 13 | 14 | void check_dostring(lua_State* L, char const* s); 15 | void require_dostring(lua_State* L, char const* s); 16 | -------------------------------------------------------------------------------- /test/test_suffix.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifdef APOLLO_TEST_SUFFIX_HPP_INCLUDED 6 | # error Test suffix may only be included once. 7 | #endif 8 | #ifndef APOLLO_TEST_PREFIX_HPP_INCLUDED 9 | # error Test prefix not included before suffix! 10 | #endif 11 | #define APOLLO_TEST_SUFFIX_HPP_INCLUDED APOLLO_TEST_SUFFIX_HPP_INCLUDED 12 | 13 | BOOST_AUTO_TEST_SUITE_END() 14 | -------------------------------------------------------------------------------- /test/test_prefix.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifdef APOLLO_TEST_PREFIX_HPP_INCLUDED 6 | # error Test prefix may only be included once. 7 | #endif 8 | #define APOLLO_TEST_PREFIX_HPP_INCLUDED APOLLO_TEST_PREFIX_HPP_INCLUDED 9 | 10 | #include "testutil.hpp" 11 | 12 | #include 13 | 14 | BOOST_FIXTURE_TEST_SUITE( 15 | BOOST_JOIN(BOOST_TEST_MODULE, _suite), 16 | lstate_fixture) 17 | -------------------------------------------------------------------------------- /include/apollo/detail/variadic_pass.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_DETAIL_VARIADIC_PASS_HPP_INCLUDED 6 | #define APOLLO_DETAIL_VARIADIC_PASS_HPP_INCLUDED APOLLO_DETAIL_VARIADIC_PASS_HPP_INCLUDED 7 | 8 | namespace apollo { namespace detail { 9 | 10 | template 11 | void variadic_pass(Ts&&...) 12 | {} 13 | 14 | } } // namespace apollo::detail 15 | 16 | #endif // APOLLO_DETAIL_VARIADIC_PASS_HPP_INCLUDED 17 | -------------------------------------------------------------------------------- /include/apollo/detail/clang_stdlib_config.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | 7 | // Let's hope for the best: 8 | #undef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE 9 | #undef BOOST_NO_CXX11_HDR_FORWARD_LIST 10 | #undef BOOST_NO_CXX11_HDR_INITIALIZER_LIST 11 | #undef BOOST_NO_CXX11_HDR_MUTEX 12 | #undef BOOST_NO_CXX11_HDR_RATIO 13 | #undef BOOST_NO_CXX11_HDR_SYSTEM_ERROR 14 | #undef BOOST_NO_CXX11_SMART_PTR 15 | -------------------------------------------------------------------------------- /doc/examples/raw_function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace { 6 | 7 | bool is_odd(int n) 8 | { 9 | return n % 2 != 0; 10 | } 11 | 12 | } // anonymous namespace 13 | 14 | int main() 15 | { 16 | apollo::closing_lstate L; 17 | luaL_openlibs(L); 18 | 19 | auto is_odd_rf = apollo::to_raw_function(); 20 | apollo::push(L, is_odd_rf); 21 | // Or, equivalently, even: lua_pushcfunction(L, is_odd_rf.f); 22 | lua_setglobal(L, "is_odd"); 23 | luaL_dostring(L, "print(is_odd(4), is_odd(5))"); // --> false true 24 | } 25 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | # This file is subject to the terms of the BSD 2-Clause License. 3 | # See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | set (EXAMPLES 6 | basic-push-to 7 | basic-create_table 8 | basic-class 9 | raw_function 10 | ) 11 | 12 | foreach(example ${EXAMPLES}) 13 | add_executable(ex_${example} "examples/${example}.cpp") 14 | target_link_libraries(ex_${example} apollo) 15 | set_target_properties(ex_${example} PROPERTIES 16 | FOLDER "Examples" 17 | COMPILE_DEFINITIONS "BOOST_TEST_MODULE=${example}") 18 | endforeach() 19 | 20 | needs_apollo_dll(ex_basic-push-to) # Any target is enough. 21 | -------------------------------------------------------------------------------- /include/apollo/typeid.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_TYPEID_HPP_INCLUDED 6 | #define APOLLO_TYPEID_HPP_INCLUDED TYPEID_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace apollo { 15 | 16 | APOLLO_API boost::typeindex::type_info const& lbuiltin_typeid(int id); 17 | 18 | APOLLO_API boost::typeindex::type_info const& ltypeid(lua_State* L, int idx); 19 | 20 | } // namespace apollo 21 | 22 | 23 | #endif // APOLLO_TYPEID_HPP_INCLUDED 24 | -------------------------------------------------------------------------------- /src/builtin_types.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | 7 | #include 8 | 9 | unsigned apollo::detail::string_conversion_steps::get( 10 | lua_State* L, int idx) 11 | { 12 | switch(lua_type(L, idx)) { 13 | case LUA_TSTRING: 14 | return lua_rawlen(L, idx) == 1 ? 0 : no_conversion; 15 | case LUA_TNUMBER: { 16 | lua_Number n = lua_tonumber(L, idx); 17 | return n >= 0 && n < 10 && n == std::floor(n) ? 18 | 2 : no_conversion; 19 | } 20 | default: 21 | return no_conversion; 22 | } 23 | BOOST_UNREACHABLE_RETURN(no_conversion); 24 | } 25 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to apollo's documentation! 2 | ================================== 3 | 4 | apollo is a library that enables working with C++ classes and functions as if 5 | they were builtin Lua types. It provides both relatively low-level APIs that you 6 | can use to build your own abstractions and ready-to-use syntactic sugar for 7 | table and class creation. 8 | 9 | apollo was inspired by luabind but prioritizes flexibility, performance and 10 | seamless integration with the Lua API. As a consequence, apollo offers (as of 11 | yet) no complete class model (Lua doesn't have one) but instead provides you 12 | with the means to easily build your own. 13 | 14 | Contents: 15 | 16 | .. toctree:: 17 | :maxdepth: 2 18 | 19 | basic-usage 20 | building 21 | converter-basics 22 | functions 23 | classes 24 | sugar 25 | utilities 26 | converter-advanced 27 | 28 | Indices and tables 29 | ================== 30 | 31 | * :ref:`genindex` 32 | * :ref:`search` 33 | 34 | -------------------------------------------------------------------------------- /include/apollo/ctor_wrapper.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_CTOR_WRAPPER_HPP_INCLUDED 6 | #define APOLLO_CTOR_WRAPPER_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace apollo { 13 | 14 | template 15 | T ctor_wrapper(Args... args) 16 | { 17 | return T(std::forward(args)...); 18 | } 19 | 20 | template < 21 | typename T, typename... Args, 22 | typename _ptr = typename std::conditional< 23 | detail::pointer_traits::is_valid, T, T*>::type> 24 | _ptr new_wrapper(Args... args) 25 | { 26 | using obj_t = typename detail::pointer_traits::pointee_type; 27 | return static_cast<_ptr>(new obj_t(std::forward(args)...)); 28 | } 29 | 30 | } // namespace apollo 31 | 32 | #endif // APOLLO_CTOR_WRAPPER_HPP_INCLUDED 33 | -------------------------------------------------------------------------------- /test/test_ward_ptr.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | #include 7 | 8 | #include "test_prefix.hpp" 9 | 10 | struct warded : apollo::enable_ward_ptr_from_this {}; 11 | 12 | 13 | BOOST_AUTO_TEST_CASE(ward_ptr_basic) 14 | { 15 | std::unique_ptr p(new warded); 16 | apollo::ward_ptr wp(p.get()); 17 | BOOST_CHECK_EQUAL(wp.get(), p.get()); 18 | BOOST_CHECK_EQUAL(wp.get(), p->ref().get()); 19 | BOOST_CHECK(wp.valid()); 20 | BOOST_CHECK(!!wp); 21 | p.reset(); 22 | BOOST_CHECK_EQUAL(wp.get(), static_cast(nullptr)); 23 | BOOST_CHECK(!wp.valid()); 24 | BOOST_CHECK(!wp); 25 | 26 | BOOST_CHECK_THROW(*wp, apollo::bad_ward_ptr); 27 | } 28 | 29 | // TODO: copy, move constructor, assignment operator; derived classes, ref() 30 | 31 | #include "test_suffix.hpp" 32 | -------------------------------------------------------------------------------- /include/apollo/detail/light_key.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_LIGHT_KEY_HPP_INCLUDED 6 | #define APOLLO_LIGHT_KEY_HPP_INCLUDED APOLLO_LIGHT_KEY_HPP_INCLUDED 7 | 8 | #include 9 | 10 | namespace apollo { 11 | 12 | namespace detail { 13 | 14 | struct light_key { 15 | operator void* () { 16 | return this; 17 | } 18 | operator void const* () const { 19 | return this; 20 | } 21 | }; 22 | 23 | } // namespace detail 24 | 25 | template<> 26 | struct converter: converter_base> { 27 | 28 | static int push(lua_State* L, detail::light_key const& lk) 29 | { 30 | lua_pushlightuserdata(L, const_cast( 31 | static_cast(lk))); 32 | return 1; 33 | } 34 | }; 35 | 36 | } // namespace apollo 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/apollo/stack_balance.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_STACK_BALANCE_HPP_INCLUDED 6 | #define APOLLO_STACK_BALANCE_HPP_INCLUDED APOLLO_STACK_POP_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace apollo { 13 | 14 | class APOLLO_API stack_balance { 15 | public: 16 | enum action { pop = 1, push_nil = 2, adjust = pop | push_nil, debug = 4 }; 17 | explicit stack_balance( 18 | lua_State* L, 19 | int diff = 0, 20 | int act = pop|debug); 21 | ~stack_balance(); 22 | 23 | // MSVC complained that the assignment operator could not be generated. 24 | stack_balance& operator=(stack_balance const&) = delete; 25 | 26 | private: 27 | lua_State* const m_L; 28 | int const m_desired_top; 29 | int const m_action; 30 | }; 31 | 32 | } // namespace apollo 33 | 34 | #endif // APOLLO_STACK_POP_HPP_INCLUDED 35 | -------------------------------------------------------------------------------- /doc/examples/basic-create_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace { 7 | 8 | bool is_odd(int n) 9 | { 10 | return n % 2 != 0; 11 | } 12 | 13 | double sqr(double n) 14 | { 15 | return n * n; 16 | } 17 | 18 | double half(double n) 19 | { 20 | return n / 2; 21 | } 22 | 23 | } // anonymous namespace 24 | 25 | int main() 26 | { 27 | apollo::closing_lstate L; 28 | luaL_openlibs(L); 29 | 30 | lua_pushglobaltable(L); 31 | apollo::rawset_table(L, -1) 32 | ("global_constant", 42) 33 | ("is_odd", &is_odd) 34 | .subtable("mymodule") 35 | ("module_version", "0.1.0-dev") 36 | ("sqr", &sqr) 37 | ("half", &half) 38 | .end_subtable(); 39 | lua_pop(L, 1); 40 | 41 | luaL_dostring(L, 42 | "print(global_constant, is_odd)\n" 43 | "print(mymodule, mymodule.module_version)\n" 44 | "print(is_odd(3), is_odd(5))\n" 45 | "print(mymodule.half(61), mymodule.sqr(8))\n"); 46 | } 47 | -------------------------------------------------------------------------------- /src/error.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | APOLLO_API int apollo::detail::push_current_exception_string( 4 | lua_State* L) BOOST_NOEXCEPT 5 | { 6 | int arg = 0; 7 | try { 8 | throw; 9 | } catch(to_cpp_conversion_error const& e) { 10 | // TODO: Check for nullptr. 11 | arg = *boost::get_error_info(e); 12 | lua_pushfstring(L, "%s [%s -> %s]", 13 | boost::get_error_info(e)->c_str(), 14 | luaL_typename(L, arg), 15 | boost::get_error_info(e)->c_str()); 16 | } catch(std::exception const& e) { 17 | lua_pushfstring(L, "exception: %s", e.what()); 18 | } catch(...) { 19 | lua_pushliteral(L, "unknown exception"); 20 | } 21 | return arg; 22 | 23 | } 24 | 25 | APOLLO_API BOOST_NORETURN void 26 | apollo::detail::error_from_pushed_exception_string( 27 | lua_State* L, int arg) BOOST_NOEXCEPT 28 | { 29 | if (arg) 30 | luaL_argerror(L, arg, lua_tostring(L, -1)); 31 | lua_error(L); 32 | std::abort(); // Should never be reached. 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/function.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | static apollo::detail::light_key function_tag = {}; 10 | 11 | APOLLO_API boost::typeindex::type_info const& apollo::detail::function_type( 12 | lua_State* L, int idx) 13 | { 14 | stack_balance b(L); 15 | 16 | if (!lua_getupvalue(L, idx, fn_upval_tag)) 17 | return boost::typeindex::type_id().type_info(); 18 | if (lua_touserdata(L, -1) != function_tag) 19 | return boost::typeindex::type_id().type_info(); 20 | lua_pop(L, 1); // Necessary to keep idx correct: 21 | BOOST_VERIFY(lua_getupvalue(L, idx, fn_upval_type)); 22 | return *static_cast( 23 | lua_touserdata(L, -1)); 24 | } 25 | 26 | APOLLO_API void apollo::detail::push_function_tag(lua_State* L) 27 | { 28 | lua_pushlightuserdata(L, function_tag); 29 | } 30 | -------------------------------------------------------------------------------- /test/test_call_by_ref.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "test_prefix.hpp" 11 | 12 | 13 | namespace { 14 | 15 | struct foo_cls { 16 | int i; 17 | }; 18 | 19 | void inc_foos(foo_cls& foo1, foo_cls& foo2) 20 | { 21 | ++foo1.i; 22 | ++foo2.i; 23 | } 24 | 25 | } // anonymous namespace 26 | 27 | // This tests that even the second argument of a function can correctly be 28 | // passed by reference (even though the current implementation stores the 29 | // arguments temporarily in a std::tuple and uses std::tuple_cat). 30 | BOOST_AUTO_TEST_CASE(call_by_ref) 31 | { 32 | apollo::register_class(L); 33 | foo_cls foo1 {0}, foo2 {2}; 34 | apollo::push(L, &inc_foos, &foo1, &foo2); 35 | apollo::pcall(L, 2, 0); 36 | BOOST_CHECK_EQUAL(foo1.i, 1); 37 | BOOST_CHECK_EQUAL(foo2.i, 3); 38 | } 39 | 40 | #include "test_suffix.hpp" 41 | -------------------------------------------------------------------------------- /doc/examples/basic-push-to.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace { 9 | 10 | bool is_odd(int n) 11 | { 12 | return n % 2 != 0; 13 | } 14 | 15 | } // anonymous namespace 16 | 17 | int main() 18 | { 19 | apollo::closing_lstate L; 20 | luaL_openlibs(L); 21 | 22 | apollo::push(L, 42); // Same as lua_pushinteger(L, 42) 23 | assert(apollo::to(L, -1) == 42); 24 | lua_pop(L, 1); 25 | 26 | apollo::push(L, &is_odd); // Functions can be pushed just like other types. 27 | lua_setglobal(L, "is_odd"); 28 | luaL_dostring(L, "print(is_odd(4), is_odd(5))"); // --> false true 29 | 30 | // Pushed functions can be retrieved back: 31 | lua_getglobal(L, "is_odd"); 32 | assert(apollo::to(L, -1) == &is_odd); 33 | 34 | 35 | // Lua functions can be retrieved as boost:: or std::function 36 | luaL_dostring(L, "function is_even(n) return n % 2 == 0 end"); 37 | lua_getglobal(L, "is_even"); 38 | auto is_even = apollo::to>(L, -1); 39 | assert(is_even(4)); 40 | assert(!is_even(5)); 41 | } 42 | -------------------------------------------------------------------------------- /include/apollo/detail/integer_seq.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_INTEGER_SEQ_HPP_INCLUDED 6 | #define APOLLO_INTEGER_SEQ_HPP_INCLUDED APOLLO_INTEGER_SEQ_HPP_INCLUDED 7 | 8 | // Integer sequence adapted from http://stackoverflow.com/a/17426611/2128694 9 | 10 | namespace apollo { namespace detail { 11 | 12 | template struct iseq{ using type = iseq; }; 13 | 14 | template struct concat_iseq; 15 | 16 | template 17 | struct concat_iseq, iseq> 18 | : iseq{}; 19 | 20 | 21 | template 22 | struct gen_iseq : concat_iseq< 23 | typename gen_iseq::type, 24 | typename gen_iseq::type> 25 | {}; 26 | 27 | template struct gen_iseq<0, Lo> : iseq<>{}; 28 | template struct gen_iseq<1, Lo> : iseq{}; 29 | 30 | template 31 | using iseq_n_t = typename gen_iseq::type; 32 | 33 | }} // namespace apollo::detail 34 | 35 | #endif // APOLLO_INTEGER_SEQ_HPP_INCLUDED 36 | -------------------------------------------------------------------------------- /include/apollo/closing_lstate.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_CLOSING_LSTATE_HPP_INCLUDED 6 | #define APOLLO_CLOSING_LSTATE_HPP_INCLUDED 7 | 8 | #include 9 | 10 | namespace apollo { 11 | 12 | class closing_lstate { 13 | public: 14 | explicit closing_lstate(lua_State* L): m_L(L) {} 15 | 16 | closing_lstate(): m_L(luaL_newstate()) {} 17 | 18 | closing_lstate(closing_lstate&& other) 19 | : m_L(other.m_L) 20 | { 21 | other.m_L = nullptr; 22 | } 23 | 24 | closing_lstate& operator= (closing_lstate&& other) 25 | { 26 | m_L = other.m_L; 27 | other.m_L = nullptr; 28 | return *this; 29 | } 30 | 31 | ~closing_lstate() 32 | { 33 | if (m_L) 34 | lua_close(m_L); 35 | } 36 | 37 | operator lua_State* () 38 | { 39 | return m_L; 40 | } 41 | 42 | lua_State* get() 43 | { 44 | return m_L; 45 | } 46 | 47 | private: 48 | lua_State* m_L; 49 | }; 50 | 51 | } // namespace apollo 52 | 53 | #endif // APOLLO_CLOSING_LSTATE_HPP_INCLUDED 54 | -------------------------------------------------------------------------------- /include/apollo/lapi.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_LAPI_HPP_INCLUDED 6 | #define APOLLO_LAPI_HPP_INCLUDED APOLLO_LAPI_HPP_INCLUDED 7 | 8 | #include 9 | 10 | namespace apollo { 11 | 12 | APOLLO_API void set_error_msg_handler(lua_State* L); 13 | APOLLO_API bool push_error_msg_handler(lua_State* L); 14 | 15 | APOLLO_API void pcall(lua_State* L, int nargs, int nresults, int msgh); 16 | APOLLO_API void pcall(lua_State* L, int nargs, int nresults); 17 | 18 | // for k, v in pairs(with) do t[k] = v end, but uses rawset and next. 19 | // Error reporting: lua_error 20 | APOLLO_API void extend_table(lua_State* L, int t, int with); 21 | 22 | // max_depth = 0: Do nothing. 23 | // max_depth = 1: Same as extend_table(L, t, with). 24 | // max_depth = n: For each t[k] and with[k] that are both tables, recursively 25 | // call extend_table_deep(L, t[k], with[k], n - 1). 26 | // Otherwise set t[k] = with[k]. 27 | // Error reporting: lua_error 28 | APOLLO_API void extend_table_deep(lua_State* L, 29 | int t, int with, unsigned max_depth = 2); 30 | 31 | } // namespace apollo 32 | 33 | #endif // APOLLO_LAPI_HPP_INCLUDED 34 | -------------------------------------------------------------------------------- /src/stack_balance.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace apollo { 10 | 11 | stack_balance::stack_balance(lua_State* L, int diff, int act) 12 | : m_L((BOOST_ASSERT(L), L)) 13 | , m_desired_top(lua_gettop(L) + diff) 14 | , m_action(act) 15 | { 16 | BOOST_ASSERT(m_desired_top >= 0); 17 | 18 | // When adjusting, debug makes no sense because 19 | // all errors are corrected automatically. 20 | BOOST_ASSERT((act & adjust) != adjust || !(act & debug)); 21 | } 22 | 23 | stack_balance::~stack_balance() 24 | { 25 | int const top = lua_gettop(m_L); 26 | if (top > m_desired_top) { 27 | if (m_action & pop) 28 | lua_settop(m_L, m_desired_top); 29 | else if (m_action & debug) 30 | BOOST_ASSERT("unbalanced stack: too many elements" && false); 31 | } else if (top < m_desired_top) { 32 | if (m_action & push_nil) 33 | lua_settop(m_L, m_desired_top); 34 | else if (m_action & debug) 35 | BOOST_ASSERT("unbalanced stack: too few elements" && false); 36 | } 37 | } 38 | 39 | } // namespace apollo 40 | -------------------------------------------------------------------------------- /include/apollo/detail/meta_util.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_DETAIL_META_UTIL_HPP_INCLUDED 6 | #define APOLLO_DETAIL_META_UTIL_HPP_INCLUDED APOLLO_DETAIL_META_UTIL_HPP_INCLUDED 7 | 8 | #include 9 | 10 | namespace apollo { namespace detail { 11 | 12 | // Helper type function remove_cvr 13 | template 14 | using remove_cvr = typename std::remove_cv< 15 | typename std::remove_reference::type>::type; 16 | 17 | template 18 | struct is_const_reference: std::integral_constant::value && 20 | std::is_const::type>::value> 21 | {}; 22 | 23 | template 24 | using is_mem_fn = std::is_member_function_pointer>; 25 | 26 | struct failure_t; 27 | 28 | template 29 | using has_failed = std::is_same; 30 | 31 | template 32 | T msvc_decltype_helper(T); // Intentionally not implemented. 33 | 34 | }} // namespace apollo::detail 35 | 36 | #define APOLLO_FN_DECLTYPE(...) decltype( \ 37 | ::apollo::detail::msvc_decltype_helper(__VA_ARGS__)) 38 | 39 | #endif // APOLLO_DETAIL_META_UTIL_HPP_INCLUDED 40 | -------------------------------------------------------------------------------- /include/apollo/emplace_ctor.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_EMPLACE_CTOR_HPP_INCLUDED 6 | #define APOLLO_EMPLACE_CTOR_HPP_INCLUDED 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace apollo { 13 | 14 | namespace detail { 15 | 16 | template 17 | int emplace_ctor_wrapper_impl(lua_State* L, ArgTuple& args, iseq) 18 | { 19 | emplace_object(L, unwrap_ref(std::get(args))...); 20 | (void)args; 21 | return 1; 22 | } 23 | 24 | template 25 | int emplace_ctor_wrapper(lua_State* L) 26 | { 27 | auto args = to_tuple(L, 1, pull_converter_for()...); 28 | return emplace_ctor_wrapper_impl(L, args, tuple_seq()); 29 | } 30 | 31 | } // namespace detail 32 | 33 | template 34 | BOOST_CONSTEXPR raw_function get_raw_emplace_ctor_wrapper() BOOST_NOEXCEPT 35 | { 36 | return raw_function::caught<&detail::emplace_ctor_wrapper>(); 37 | } 38 | 39 | 40 | 41 | } // namespace apollo 42 | 43 | #endif // APOLLO_EMPLACE_CTOR_HPP_INCLUDED 44 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | apollo -- Copyright (c) 2015, Christian Neumüller 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 | POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | # This file is subject to the terms of the BSD 2-Clause License. 3 | # See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | add_library(testutil STATIC 6 | testutil.hpp testutil.cpp 7 | test_prefix.hpp test_suffix.hpp) 8 | 9 | target_link_libraries(testutil 10 | apollo ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) 11 | 12 | needs_apollo_dll(testutil) 13 | 14 | set (TESTS 15 | call_by_ref 16 | create_class 17 | create_table 18 | default_argument 19 | function_converters 20 | implicit_ctor 21 | lua_utils 22 | object_converters 23 | overloadset 24 | property 25 | reference 26 | simple_converters 27 | typeid 28 | ward_ptr 29 | wstring 30 | ) 31 | 32 | if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") 33 | add_definitions("-Wno-global-constructors" "-Wno-exit-time-destructors") 34 | endif() 35 | 36 | foreach(test ${TESTS}) 37 | add_executable(test_${test} test_${test}.cpp) 38 | target_link_libraries(test_${test} testutil) 39 | set_target_properties(test_${test} PROPERTIES 40 | FOLDER "Tests" 41 | COMPILE_DEFINITIONS "BOOST_TEST_MODULE=${test}") 42 | add_test(NAME ${test} COMMAND test_${test}) 43 | endforeach() 44 | 45 | add_executable(benchmark "benchmark.cpp") 46 | target_link_libraries(benchmark ${LUA_LIBRARIES} apollo) 47 | -------------------------------------------------------------------------------- /cmake/Modules/FindApollo.cmake: -------------------------------------------------------------------------------- 1 | # Locate apollo library 2 | 3 | FIND_PATH(APOLLO_INCLUDE_DIRS "apollo/function.hpp" 4 | HINTS $ENV{APOLLO_DIR} 5 | PATH_SUFFIXES apollo/include include 6 | ) 7 | 8 | FIND_LIBRARY(_APOLLO_LIBRARY_RELEASE 9 | NAMES apollo 10 | HINTS $ENV{APOLLO_DIR} 11 | PATH_SUFFIXES apollo/lib lib 12 | ) 13 | 14 | FIND_LIBRARY(_APOLLO_LIBRARY_DEBUG 15 | NAMES apollo-d 16 | HINTS $ENV{APOLLO_DIR} 17 | PATH_SUFFIXES apollo/lib lib 18 | ) 19 | 20 | IF(_APOLLO_LIBRARY_RELEASE OR _APOLLO_LIBRARY_DEBUG) 21 | IF(_APOLLO_LIBRARY_RELEASE AND _APOLLO_LIBRARY_DEBUG) 22 | SET(_APOLLO_LIBRARY optimized ${_APOLLO_LIBRARY_RELEASE} 23 | debug ${_APOLLO_LIBRARY_DEBUG}) 24 | ELSEIF(_APOLLO_LIBRARY_RELEASE) 25 | SET(_APOLLO_LIBRARY ${_APOLLO_LIBRARY_RELEASE}) 26 | ELSE() 27 | SET(_APOLLO_LIBRARY ${_APOLLO_LIBRARY_DEBUG}) 28 | ENDIF() 29 | ENDIF() 30 | 31 | IF(_APOLLO_LIBRARY) 32 | SET(APOLLO_LIBRARIES 33 | "${_APOLLO_LIBRARY}" CACHE STRING "apollo Libraries") 34 | ENDIF(_APOLLO_LIBRARY) 35 | 36 | INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) 37 | # handle the QUIETLY and REQUIRED arguments and set APOLLO_FOUND to TRUE if 38 | # all listed variables are TRUE 39 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(apollo 40 | REQUIRED_VARS APOLLO_INCLUDE_DIRS APOLLO_LIBRARIES) 41 | 42 | MARK_AS_ADVANCED(APOLLO_INCLUDE_DIRS APOLLO_LIBRARIES) 43 | -------------------------------------------------------------------------------- /doc/examples/basic-class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace { 12 | 13 | class my_class { 14 | public: 15 | my_class(int foo_, char bar): foo(foo_), m_bar(bar) 16 | { } 17 | 18 | int foo; // Just for demonstration. 19 | 20 | void print_bar() 21 | { 22 | std::cout << "my_class::m_bar: " << m_bar << '\n'; 23 | } 24 | 25 | private: 26 | char m_bar; 27 | }; 28 | 29 | } // anonymous namespace 30 | 31 | int main() 32 | { 33 | apollo::closing_lstate L; 34 | luaL_openlibs(L); 35 | 36 | apollo::register_class(L); 37 | 38 | 39 | lua_pushglobaltable(L); 40 | apollo::rawset_table(L, -1) 41 | ("MyClass", &apollo::ctor_wrapper); 42 | lua_pop(L, 1); 43 | 44 | apollo::push_class_metatable(L); 45 | apollo::rawset_table(L, -1) 46 | .thistable_as("__index") // getmetatable(T).__index = getmetatable(T) 47 | ("foo", &APOLLO_MEMBER_GETTER(my_class::foo)) 48 | ("set_foo", &APOLLO_MEMBER_SETTER(my_class::foo)) 49 | ("print_bar", &my_class::print_bar); 50 | lua_pop(L, 1); 51 | 52 | luaL_dostring(L, 53 | "local mc = MyClass(42, 'a')\n" 54 | "mc:print_bar()\n" 55 | "print(mc:foo())\n" 56 | "mc:set_foo(7)\n" 57 | "print(mc:foo())\n"); 58 | } 59 | -------------------------------------------------------------------------------- /test/test_wstring.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | 7 | #ifndef APOLLO_NO_WSTRING 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | using apollo::detail::to_wstring; 17 | using apollo::detail::from_wstring; 18 | 19 | namespace std { 20 | 21 | inline std::ostream& operator<<(std::ostream& out, const std::wstring& value) 22 | { 23 | return out << from_wstring(value.c_str(), value.size()); 24 | } 25 | 26 | } 27 | #include "test_prefix.hpp" 28 | 29 | 30 | static std::wstring tow(std::string s) { 31 | return to_wstring(s.c_str(), s.size()); 32 | } 33 | 34 | static std::string fromw(std::wstring s) { 35 | return from_wstring(s.c_str(), s.size()); 36 | } 37 | 38 | BOOST_AUTO_TEST_CASE(to_wstring_backend) 39 | { 40 | BOOST_CHECK_EQUAL(tow(""), L""); 41 | BOOST_CHECK_EQUAL(tow("abc"), L"abc"); 42 | BOOST_CHECK_EQUAL(tow(u8"Öß"), L"Öß"); 43 | } 44 | 45 | BOOST_AUTO_TEST_CASE(from_wstring_backend) 46 | { 47 | BOOST_CHECK_EQUAL(fromw(L""), ""); 48 | BOOST_CHECK_EQUAL(fromw(L"abc"), "abc"); 49 | BOOST_CHECK_EQUAL(fromw(L"Öß"), u8"Öß"); 50 | } 51 | 52 | #include "test_suffix.hpp" 53 | 54 | #else // APOLLO_NO_WSTRING 55 | int main() { } 56 | #endif // APOLLO_NO_WSTRING / else 57 | -------------------------------------------------------------------------------- /src/typeid.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace { 11 | struct table_tag {}; 12 | } 13 | 14 | APOLLO_API boost::typeindex::type_info const& apollo::lbuiltin_typeid(int id) 15 | { 16 | using boost::typeindex::type_id; 17 | switch (id) { 18 | case LUA_TBOOLEAN: return type_id().type_info(); 19 | case LUA_TFUNCTION: return type_id().type_info(); 20 | case LUA_TLIGHTUSERDATA: return type_id().type_info(); 21 | case LUA_TNIL: 22 | case LUA_TNONE: return type_id().type_info(); 23 | case LUA_TNUMBER: return type_id().type_info(); 24 | case LUA_TSTRING: return type_id().type_info(); 25 | case LUA_TTABLE: return type_id().type_info(); 26 | case LUA_TTHREAD: return type_id().type_info(); 27 | case LUA_TUSERDATA: return type_id().type_info(); 28 | 29 | default: 30 | BOOST_ASSERT_MSG(false, "id is not a valid lua type id"); 31 | return type_id().type_info(); 32 | } 33 | } 34 | 35 | APOLLO_API boost::typeindex::type_info const& apollo::ltypeid( 36 | lua_State* L, int idx) 37 | { 38 | if (detail::is_apollo_instance(L, idx)) 39 | return *detail::as_holder(L, idx)->type().rtti_type; 40 | return lbuiltin_typeid(lua_type(L, idx)); 41 | } 42 | -------------------------------------------------------------------------------- /include/apollo/lua_include.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_LUA_INCLUDE_HPP_INCLUDED 6 | #define APOLLO_LUA_INCLUDE_HPP_INCLUDED 7 | 8 | extern "C" { 9 | #include 10 | #include 11 | #include 12 | } 13 | 14 | #if LUA_VERSION_NUM < 502 15 | #include 16 | 17 | # define lua_rawlen lua_objlen 18 | # define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) 19 | # define LUA_OK 0 20 | 21 | namespace apollo { namespace detail { 22 | 23 | inline bool is_relative_index(int idx) 24 | { 25 | return idx < 0 && idx > LUA_REGISTRYINDEX; 26 | } 27 | 28 | } } // namespace apollo::detail 29 | 30 | inline int lua_absindex(lua_State* L, int idx) 31 | { 32 | return apollo::detail::is_relative_index(idx) ? 33 | lua_gettop(L) + idx + 1 : idx; 34 | } 35 | 36 | inline void lua_rawsetp(lua_State* L, int t, void const* k) 37 | { 38 | lua_pushlightuserdata(L, const_cast(k)); 39 | lua_insert(L, -2); // Move key beneath value. 40 | if (apollo::detail::is_relative_index(t)) 41 | t -= 1; // Adjust for pushed k. 42 | lua_rawset(L, t); 43 | } 44 | 45 | inline void lua_rawgetp(lua_State* L, int t, void const* k) 46 | { 47 | lua_pushlightuserdata(L, const_cast(k)); 48 | if (apollo::detail::is_relative_index(t)) 49 | t -= 1; // Adjust for pushed k. 50 | lua_rawget(L, t); 51 | } 52 | 53 | APOLLO_API void luaL_requiref ( 54 | lua_State *L, const char *modname, lua_CFunction openf, int glb); 55 | 56 | #endif // LUA_VERSION_NUM < 502 57 | 58 | #endif // APOLLO_LUA_INCLUDE_HPP_INCLUDED 59 | -------------------------------------------------------------------------------- /test/testutil.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include "testutil.hpp" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include // std::terminate() 15 | #include // std::cerr 16 | 17 | // See http://stackoverflow.com/a/5402543/2128694 for boost::exception support 18 | 19 | namespace { 20 | 21 | inline void translateBoostException(const boost::exception &e) 22 | { 23 | BOOST_FAIL(boost::diagnostic_information(e)); 24 | } 25 | 26 | struct boost_exception_fixture { 27 | boost_exception_fixture() 28 | { 29 | boost::unit_test::unit_test_monitor.register_exception_translator< 30 | boost::exception>(&translateBoostException); 31 | } 32 | }; 33 | 34 | BOOST_GLOBAL_FIXTURE(boost_exception_fixture) 35 | #if BOOST_VERSION >= 105900 36 | ; 37 | #endif 38 | 39 | } // anonymous namespace 40 | 41 | lstate_fixture::lstate_fixture() 42 | { 43 | L = luaL_newstate(); 44 | BOOST_REQUIRE(L); 45 | } 46 | 47 | lstate_fixture::~lstate_fixture() 48 | { 49 | BOOST_CHECK_EQUAL(lua_gettop(L), 0); 50 | lua_close(L); 51 | } 52 | 53 | void check_dostring(lua_State* L, char const* s) 54 | { 55 | if (luaL_dostring(L, s)) { 56 | BOOST_ERROR(lua_tostring(L, -1)); 57 | lua_pop(L, 1); 58 | } 59 | } 60 | 61 | void require_dostring(lua_State* L, char const* s) 62 | { 63 | apollo::stack_balance balance(L); 64 | if (luaL_dostring(L, s)) 65 | BOOST_FAIL(lua_tostring(L, -1)); 66 | } 67 | -------------------------------------------------------------------------------- /include/apollo/detail/smart_ptr.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_DETAIL_SMART_PTR_HPP_INCLUDED 6 | #define APOLLO_DETAIL_SMART_PTR_HPP_INCLUDED APOLLO_DETAIL_SMART_PTR_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #include 11 | 12 | #ifdef BOOST_NO_CXX11_SMART_PTR 13 | # error No C++11 smart pointers. 14 | #endif 15 | 16 | namespace apollo { namespace detail { 17 | 18 | // Automatically recognize std::shared_ptr, unique_ptr and auto_ptr. 19 | using boost::get_pointer; 20 | 21 | // Adapted from TC++PL (4th ed.) 28.4.4 (p. 800). 22 | template 23 | struct get_pointer_result { 24 | private: 25 | template 26 | static auto check(X const& x) -> decltype(get_pointer(x)); 27 | static void check(...); 28 | public: 29 | // The result type of get_pointer(arg) if there exists a get_pointer() 30 | // overload for Arg (arg's type). void otherwise. 31 | using type = decltype(check(std::declval())); 32 | }; 33 | 34 | template 35 | struct pointer_traits { 36 | using ptr_type = typename get_pointer_result::type; 37 | 38 | // Exists a get_pointer() overload for T which returns a pointer? 39 | static bool const is_valid = !std::is_same::value; 40 | 41 | using pointee_type = typename std::conditional::type, T>::type; 43 | 44 | 45 | static bool const is_smart = is_valid && !std::is_pointer::value; 46 | static bool const is_const = std::is_const::value; 47 | }; 48 | 49 | } } // namespace apollo::detail 50 | 51 | #endif // APOLLO_DETAIL_SMART_PTR_HPP_INCLUDED 52 | -------------------------------------------------------------------------------- /src/lua51compat.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | 7 | #if LUA_VERSION_NUM < 502 8 | 9 | // Taken from Lua 5.2's lauxlib.c 10 | 11 | 12 | /* 13 | ** ensure that stack[idx][fname] has a table and push that table 14 | ** into the stack 15 | */ 16 | static int luaL_getsubtable (lua_State *L, int idx, const char *fname) { 17 | lua_getfield(L, idx, fname); 18 | if (lua_istable(L, -1)) return 1; /* table already there */ 19 | else { 20 | lua_pop(L, 1); /* remove previous result */ 21 | idx = lua_absindex(L, idx); 22 | lua_newtable(L); 23 | lua_pushvalue(L, -1); /* copy to be left at top */ 24 | lua_setfield(L, idx, fname); /* assign new table to field */ 25 | return 0; /* false, because did not find table there */ 26 | } 27 | } 28 | 29 | /* 30 | ** stripped-down 'require'. Calls 'openf' to open a module, 31 | ** registers the result in 'package.loaded' table and, if 'glb' 32 | ** is true, also registers the result in the global table. 33 | ** Leaves resulting module on the top. 34 | */ 35 | APOLLO_API void luaL_requiref( 36 | lua_State *L, const char *modname, lua_CFunction openf, int glb) 37 | { 38 | lua_pushcfunction(L, openf); 39 | lua_pushstring(L, modname); /* argument to open function */ 40 | lua_call(L, 1, 1); /* open module */ 41 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); 42 | lua_pushvalue(L, -2); /* make copy of module (call result) */ 43 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ 44 | lua_pop(L, 1); /* remove _LOADED table */ 45 | if (glb) { 46 | lua_pushvalue(L, -1); /* copy of 'mod' */ 47 | lua_setglobal(L, modname); /* _G[modname] = module */ 48 | } 49 | } 50 | 51 | #endif // LUA_VERSION_NUM < 502 52 | -------------------------------------------------------------------------------- /src/class.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | #include 7 | 8 | static apollo::detail::light_key object_tag = {}; 9 | 10 | static int gc_instance(lua_State* L) BOOST_NOEXCEPT 11 | { 12 | if (!apollo::detail::is_apollo_instance(L, 1)) 13 | luaL_argerror(L, 1, "Expected apollo object."); 14 | apollo::gc_object(L); 15 | lua_pushnil(L); 16 | lua_setmetatable(L, 1); 17 | return 0; 18 | } 19 | 20 | APOLLO_API void apollo::detail::push_instance_metatable( 21 | lua_State* L, 22 | class_info const& cls) BOOST_NOEXCEPT 23 | { 24 | lua_rawgetp(L, LUA_REGISTRYINDEX, &cls); 25 | if (!lua_istable(L, -1)) { 26 | BOOST_ASSERT(lua_isnil(L, -1)); 27 | lua_pop(L, 1); 28 | 29 | lua_createtable(L, 1, 1); 30 | 31 | lua_pushlightuserdata(L, object_tag); 32 | lua_rawseti(L, -2, 1); 33 | 34 | lua_pushliteral(L, "__gc"); 35 | // Destroy through pointer to interface class. 36 | lua_pushcfunction(L, &gc_instance); 37 | lua_rawset(L, -3); 38 | 39 | // Copy metatable because we also want to return it. 40 | lua_pushvalue(L, -1); 41 | lua_rawsetp(L, LUA_REGISTRYINDEX, &cls); 42 | } 43 | #ifndef NDEBUG 44 | lua_rawgeti(L, -1, 1); 45 | BOOST_ASSERT(lua_touserdata(L, -1) == object_tag); 46 | lua_pop(L, 1); 47 | #endif 48 | } 49 | 50 | APOLLO_API bool apollo::detail::is_apollo_instance(lua_State* L, int idx) 51 | { 52 | // We don't have to check for type == userdata, as the object metatables get 53 | // a __metatable field by default, blocking Lua code from geting hold of the 54 | // object_tag. 55 | if (!lua_getmetatable(L, idx)) 56 | return false; 57 | 58 | lua_rawgeti(L, -1, 1); 59 | bool r = lua_touserdata(L, -1) == object_tag; 60 | lua_pop(L, 2); 61 | return r; 62 | } 63 | -------------------------------------------------------------------------------- /test/test_typeid.cpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #include 6 | #include 7 | 8 | #include "test_prefix.hpp" 9 | 10 | #define CHECK_TID_EQ(L, R) BOOST_CHECK_EQUAL(L.name(), R.name()) 11 | 12 | namespace { 13 | struct test_cls {}; 14 | } // anonymous namespace 15 | 16 | BOOST_AUTO_TEST_CASE(builtin_typeid) 17 | { 18 | // Use a macro to see line numbers 19 | #define CHECK_BUILTIN_T(L, R) \ 20 | CHECK_TID_EQ(apollo::lbuiltin_typeid(L), boost::typeindex::type_id()) 21 | 22 | CHECK_BUILTIN_T(LUA_TNUMBER, lua_Number); 23 | CHECK_BUILTIN_T(LUA_TBOOLEAN, bool); 24 | CHECK_BUILTIN_T(LUA_TFUNCTION, lua_CFunction); 25 | CHECK_BUILTIN_T(LUA_TSTRING, char const*); 26 | CHECK_BUILTIN_T(LUA_TTHREAD, lua_State*); 27 | CHECK_BUILTIN_T(LUA_TNIL, void); 28 | // All others are unspecified. 29 | #undef CHECK_BUILTIN_T 30 | } 31 | 32 | static int testf(lua_State*) 33 | { 34 | return 0; 35 | } 36 | 37 | BOOST_AUTO_TEST_CASE(ltypeid) 38 | { 39 | using boost::typeindex::type_id; 40 | 41 | apollo::register_class(L); 42 | 43 | lua_pushinteger(L, 42); 44 | CHECK_TID_EQ(apollo::ltypeid(L, -1), type_id()); 45 | lua_pop(L, 1); 46 | 47 | lua_pushboolean(L, true); 48 | CHECK_TID_EQ(apollo::ltypeid(L, -1), type_id()); 49 | lua_pop(L, 1); 50 | 51 | lua_pushcfunction(L, &testf); 52 | CHECK_TID_EQ(apollo::ltypeid(L, -1), type_id()); 53 | lua_pop(L, 1); 54 | 55 | apollo::push(L, test_cls()); 56 | CHECK_TID_EQ(apollo::ltypeid(L, -1), type_id()); 57 | lua_pop(L, 1); 58 | 59 | lua_newuserdata(L, sizeof(char)); 60 | CHECK_TID_EQ( 61 | apollo::ltypeid(L, -1), apollo::lbuiltin_typeid(LUA_TUSERDATA)); 62 | lua_pop(L, 1); 63 | 64 | CHECK_TID_EQ(apollo::ltypeid(L, 1), apollo::lbuiltin_typeid(LUA_TNONE)); 65 | } 66 | 67 | #include "test_suffix.hpp" 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Title: Apollo Readme 2 | 3 | # apollo 4 | Convert anything from Lua to C++ and back! 5 | 6 | [![Build Status](https://travis-ci.org/Oberon00/apollo.svg?branch=master)](https://travis-ci.org/Oberon00/apollo) 7 | 8 | This library is in a quite usable alpha state. It can be built as static library 9 | or DLL/.so and works with Lua 5.2 to 5.3. Documentation is here: 10 | 11 | **http://oberon00.github.io/apollo/** 12 | 13 | 14 | ## Features 15 | 16 | * Functions are first-class objects: You can push a function to Lua and retrieve 17 | it back. When you pushed it as a function pointer, you can retrieve it back as 18 | function pointer, std::function and boost::function are also fully supported 19 | (they can even hold functions written in Lua!) 20 | * If you don't need to retrieve your functions back from Lua, apollo offers 21 | function wrappers that have *zero overhead* compared to a hand-written 22 | wrapper (`to_raw_function()`). 23 | * Supports converting classes with multiple bases to any unambiguous one 24 | (virtual inheritance is *not* supported). 25 | * Access to primitives (`push`, `from_stack`, `is_convertible`) allows you 26 | to build the abstractions you need or hand-write a custom wrapper if the 27 | included high-level abstractions don't fit your needs. 28 | * Useful Lua programming utilities like `registry_reference`, `stack_balance` or 29 | `exceptions_to_lua_errors` and the complementary throwing `pcall`. 30 | 31 | Also, the implementation uses variadic templates instead of preprocessor 32 | metaprogramming for faster builds and better auto-completion support. 33 | 34 | 35 | ## Requirements 36 | 37 | * A up-to-date, reasonably C++11-compliant compiler and standard library. Tested 38 | with gcc 4.8, Clang 3.4 with libstdc++-4.8 (see Travis CI) and MSVC 12 (2013). 39 | * [Lua](http://lua.org) in version 5.1, 5.2 or 5.3. 40 | * [Boost 1.56](http://boost.org) Presently used modules are Assert, Config, 41 | Core, Exception and TypeIndex. For the tests, Preprocessor and Test are used 42 | additionally. 43 | * A reasonably recent [CMake](http://cmake.org) for building. 44 | -------------------------------------------------------------------------------- /include/apollo/detail/ref_binder.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_DETAIL_REF_BINDER_HPP_INCLUDED 6 | #define APOLLO_DETAIL_REF_BINDER_HPP_INCLUDED APOLLO_DETAIL_REF_BINDER_HPP_INCLUDED 7 | 8 | #include // std::move, std::forward 9 | 10 | namespace apollo { 11 | 12 | namespace detail { 13 | 14 | template 15 | class ref_binder { 16 | public: 17 | using bound_t = T&; 18 | 19 | explicit ref_binder(T& v) 20 | : m_ptr(&v), m_is_owner(false) 21 | {} 22 | 23 | ref_binder(T&& v) 24 | : m_ptr(new T(std::move(v))), m_is_owner(true) 25 | {} 26 | 27 | ref_binder(T* ptr, bool is_owner) 28 | : m_ptr(ptr), m_is_owner(is_owner) 29 | {} 30 | 31 | ref_binder(ref_binder&& other) 32 | : m_ptr(other.m_ptr), m_is_owner(other.m_is_owner) 33 | { 34 | other.m_is_owner = false; 35 | other.m_ptr = nullptr; 36 | } 37 | 38 | ref_binder(ref_binder const&) = delete; 39 | ref_binder& operator= (ref_binder const&) = delete; 40 | 41 | ~ref_binder() 42 | { 43 | if (BOOST_UNLIKELY(m_is_owner)) 44 | delete m_ptr; 45 | } 46 | 47 | T& get() const { return *m_ptr; } 48 | 49 | bool owns_object() const { return m_is_owner; } 50 | 51 | private: 52 | T* m_ptr; 53 | bool m_is_owner; 54 | }; 55 | 56 | } // namespace detail 57 | 58 | 59 | template 60 | T&& unwrap_ref(T&& v) { return std::forward(v); } 61 | 62 | template 63 | T& unwrap_ref(detail::ref_binder const& rv) { return rv.get(); } 64 | 65 | template 66 | T& unwrap_ref(detail::ref_binder& rv) { return rv.get(); } 67 | 68 | template 69 | T& unwrap_ref(detail::ref_binder&& rv) { return rv.get(); } 70 | 71 | #ifndef APOLLO_NO_WSTRING 72 | namespace detail { class wcstr_holder; } 73 | wchar_t* unwrap_ref(detail::wcstr_holder&& wh); 74 | #endif 75 | 76 | } // namespace apollo 77 | 78 | #endif // APOLLO_DETAIL_REF_BINDER_HPP_INCLUDED 79 | -------------------------------------------------------------------------------- /include/apollo/config.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_CONFIG_HPP_INCLUDED 6 | #define APOLLO_CONFIG_HPP_INCLUDED APOLLO_CONFIG_HPP_INCLUDED 7 | 8 | #include 9 | #include 10 | 11 | #define APOLLO_VERSION_MAJOR 0 12 | #define APOLLO_VERSION_MINOR 0 13 | #define APOLLO_VERSION_PATCH 0 14 | 15 | #ifndef APOLLO_API 16 | # ifdef APOLLO_DYNAMIC_LINK 17 | # if defined (BOOST_WINDOWS) 18 | # ifdef APOLLO_BUILDING 19 | # define APOLLO_API __declspec(dllexport) 20 | # else 21 | # define APOLLO_API __declspec(dllimport) 22 | # endif 23 | # elif defined (__CYGWIN__) 24 | # ifdef APOLLO_BUILDING 25 | # define APOLLO_API __attribute__ ((dllexport)) 26 | # else 27 | # define APOLLO_API __attribute__ ((dllimport)) 28 | # endif 29 | # elif defined(__GNUC__) && __GNUC__ >= 4 30 | # define APOLLO_API __attribute__ ((visibility("default"))) 31 | # endif 32 | # else 33 | # define APOLLO_API 34 | # endif 35 | #endif 36 | 37 | #if !defined(APOLLO_NO_WSTRING) && ( \ 38 | defined(BOOST_NO_INTRINSIC_WCHAR_T) \ 39 | || !defined(_WIN32) \ 40 | && ( \ 41 | defined(BOOST_NO_CXX11_HDR_CODECVT) \ 42 | || defined(BOOST_NO_0X_HDR_CODECVT))) 43 | # define APOLLO_NO_WSTRING 44 | #endif 45 | 46 | #ifdef BOOST_MSVC 47 | # define APOLLO_DETAIL_PUSHMSWARN(id) \ 48 | __pragma(warning(push)) \ 49 | __pragma(warning(disable:id)) 50 | # define APOLLO_DETAIL_POPMSWARN __pragma(warning(pop)) 51 | #else 52 | # define APOLLO_DETAIL_PUSHMSWARN(id) 53 | # define APOLLO_DETAIL_POPMSWARN 54 | #endif 55 | 56 | #define APOLLO_DETAIL_CONSTCOND_BEGIN APOLLO_DETAIL_PUSHMSWARN(4127) 57 | #define APOLLO_DETAIL_CONSTCOND_END APOLLO_DETAIL_POPMSWARN 58 | 59 | #endif // APOLLO_CONFIG_HPP_INCLUDED 60 | -------------------------------------------------------------------------------- /include/apollo/gc.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_GC_HPP_INCLUDED 6 | #define APOLLO_GC_HPP_INCLUDED APOLLO_GC_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace apollo { 18 | 19 | template 20 | int gc_object(lua_State* L) BOOST_NOEXCEPT 21 | { 22 | BOOST_ASSERT(lua_type(L, 1) == LUA_TUSERDATA); 23 | static_cast(lua_touserdata(L, 1))->~T(); 24 | return 0; 25 | } 26 | 27 | template 28 | inline detail::remove_cvr* 29 | emplace_bare_udata(lua_State* L, Args&&... ctor_args) 30 | { 31 | using obj_t = detail::remove_cvr; 32 | void* uf = lua_newuserdata(L, sizeof(obj_t)); 33 | try { 34 | return new(uf) obj_t(std::forward(ctor_args)...); 35 | } catch (...) { 36 | lua_pop(L, 1); 37 | throw; 38 | } 39 | } 40 | 41 | template 42 | inline detail::remove_cvr* 43 | push_bare_udata(lua_State* L, T&& o) 44 | { 45 | return emplace_bare_udata(L, std::forward(o)); 46 | } 47 | 48 | 49 | 50 | // Note: __gc will not unset metatable. 51 | // Use for objects that cannot be retrieved from untrusted Lua code only. 52 | template 53 | detail::remove_cvr* 54 | push_gc_object(lua_State* L, T&& o) 55 | { 56 | using obj_t = detail::remove_cvr; 57 | void* uf = push_bare_udata(L, std::forward(o)); 58 | APOLLO_DETAIL_CONSTCOND_BEGIN 59 | if (!std::is_trivially_destructible::value) { 60 | APOLLO_DETAIL_CONSTCOND_END 61 | lua_createtable(L, 0, 1); // 0 sequence entries, 1 dictionary entry 62 | lua_pushcfunction(L, &gc_object); 63 | lua_setfield(L, -2, "__gc"); 64 | lua_setmetatable(L, -2); 65 | } 66 | return static_cast(uf); 67 | } 68 | 69 | } // namespace apollo 70 | 71 | #endif // APOLLO_GC_HPP_INCLUDED 72 | -------------------------------------------------------------------------------- /include/apollo/operator.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_OPERATOR_HPP_INCLUDED 6 | #define APOLLO_OPERATOR_HPP_INCLUDED APOLLO_OPERATOR_HPP_INCLUDED 7 | 8 | namespace apollo { namespace op { 9 | 10 | 11 | #define APOLLO_DETAIL_BINOP(op, name) \ 12 | template \ 13 | auto name(Lhs lhs, Rhs rhs) \ 14 | -> decltype(lhs op rhs) \ 15 | { \ 16 | return lhs op rhs; \ 17 | } 18 | 19 | #define APOLLO_DETAIL_PREFIXOP(op, name) \ 20 | template \ 21 | auto name(Operand operand) \ 22 | -> decltype(op operand) \ 23 | { \ 24 | return op operand; \ 25 | } 26 | 27 | // Operator names follow the names of the 28 | // corresponding Lua metamethods (if any). 29 | 30 | // Arithmetic operations (all have corresponding metamethods) 31 | APOLLO_DETAIL_BINOP(+, add); 32 | APOLLO_DETAIL_BINOP(-, sub); 33 | APOLLO_DETAIL_BINOP(*, mul); 34 | APOLLO_DETAIL_BINOP(/, div); 35 | APOLLO_DETAIL_BINOP(%, mod); 36 | APOLLO_DETAIL_PREFIXOP(-, unm); 37 | 38 | // Comparisons 39 | APOLLO_DETAIL_BINOP(==, eq); // Has metamethod. 40 | APOLLO_DETAIL_BINOP(!=, ne); 41 | APOLLO_DETAIL_BINOP(>, gt); 42 | APOLLO_DETAIL_BINOP(<, lt); // Has metamethod. 43 | APOLLO_DETAIL_BINOP(>=, ge); 44 | APOLLO_DETAIL_BINOP(<=, le); // Has metamethod. 45 | 46 | // Logical operations 47 | APOLLO_DETAIL_BINOP(&&, land); 48 | APOLLO_DETAIL_BINOP(||, lor); 49 | APOLLO_DETAIL_PREFIXOP(!, lnot); 50 | 51 | // Bitwise operations (since Lua 5.3, all have corresponding metamethods) 52 | APOLLO_DETAIL_BINOP(&, band); 53 | APOLLO_DETAIL_BINOP(|, bor); 54 | APOLLO_DETAIL_BINOP(^, bxor); 55 | APOLLO_DETAIL_PREFIXOP(~, bnot); 56 | APOLLO_DETAIL_BINOP(<<, shl); 57 | APOLLO_DETAIL_BINOP(>>, shr); 58 | 59 | #undef APOLLO_DETAIL_BINOP 60 | #undef APOLLO_DETAIL_PREFIXOP 61 | 62 | } } // namespace apollo::op 63 | 64 | 65 | #endif // APOLLO_OPERATOR_HPP_INCLUDED 66 | -------------------------------------------------------------------------------- /include/apollo/detail/signature.hpp: -------------------------------------------------------------------------------- 1 | // Part of the apollo library -- Copyright (c) Christian Neumüller 2015 2 | // This file is subject to the terms of the BSD 2-Clause License. 3 | // See LICENSE.txt or http://opensource.org/licenses/BSD-2-Clause 4 | 5 | #ifndef APOLLO_DETAIL_SIGNATURE_HPP_INCLUDED 6 | #define APOLLO_DETAIL_SIGNATURE_HPP_INCLUDED 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace apollo { namespace detail { 14 | 15 | // Plain function pointer: 16 | template 17 | std::tuple signature_tuple_of_impl(R(*)(Args...)); 18 | 19 | // Function object (std::function, boost::function, etc.): 20 | template