// The MIT License (MIT) // Copyright (c) 2013-2016 Rapptz, ThePhD and contributors // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef SOL_TYPES_HPP #define SOL_TYPES_HPP #include "compatibility.hpp" #include "traits.hpp" #include "optional.hpp" #include #include namespace sol { namespace detail { #ifdef SOL_NO_EXCEPTIONS template inline int static_trampoline (lua_State* L) { return f(L); } template inline int trampoline(lua_State* L, Fx&& f, Args&&... args) { return f(L, std::forward(args)...); } inline int c_trampoline(lua_State* L, lua_CFunction f) { return trampoline(L, f); } #else template inline int static_trampoline (lua_State* L) { try { return f(L); } catch (const char *s) { lua_pushstring(L, s); } catch (const std::exception& e) { lua_pushstring(L, e.what()); } catch (...) { lua_pushstring(L, "caught (...) exception"); } return lua_error(L); } template inline int trampoline(lua_State* L, Fx&& f, Args&&... args) { try { return f(L, std::forward(args)...); } catch (const char *s) { lua_pushstring(L, s); } catch (const std::exception& e) { lua_pushstring(L, e.what()); } catch (...) { lua_pushstring(L, "caught (...) exception"); } return lua_error(L); } inline int c_trampoline(lua_State* L, lua_CFunction f) { return trampoline(L, f); } #endif // Exceptions vs. No Exceptions struct empty { void operator()() {} }; template struct unique_usertype {}; } // detail struct nil_t {}; const nil_t nil {}; struct metatable_key_t {}; const metatable_key_t metatable_key = {}; inline bool operator==(nil_t, nil_t) { return true; } inline bool operator!=(nil_t, nil_t) { return false; } typedef std::remove_pointer_t lua_r_CFunction; template struct unique_usertype_traits { typedef T type; typedef T actual_type; static const bool value = false; template static bool is_null(U&&) { return false; } template static auto get(U&& value) { return std::addressof(detail::deref(value)); } }; template struct unique_usertype_traits> { typedef T type; typedef std::shared_ptr actual_type; static const bool value = true; static bool is_null(const actual_type& value) { return value == nullptr; } static type* get(const actual_type& p) { return p.get(); } }; template struct unique_usertype_traits> { typedef T type; typedef std::unique_ptr actual_type; static const bool value = true; static bool is_null(const actual_type& value) { return value == nullptr; } static type* get(const actual_type& p) { return p.get(); } }; template struct non_null {}; template struct function_sig {}; struct up_value_index { int index; up_value_index(int idx) : index(lua_upvalueindex(idx)) {} operator int() const { return index; } }; struct absolute_index { int index; absolute_index(lua_State* L, int idx) : index(lua_absindex(L, idx)) {} operator int() const { return index; } }; struct light_userdata_value { void* value; light_userdata_value(void* data) : value(data) {} operator void*() const { return value; } }; struct userdata_value { void* value; userdata_value(void* data) : value(data) {} operator void*() const { return value; } }; struct c_closure { lua_CFunction c_function; int upvalues; c_closure(lua_CFunction f, int upvalues = 0) : c_function(f), upvalues(upvalues) {} }; struct this_state { lua_State* L; operator lua_State* () const { return L; } lua_State* operator-> () const { return L; } }; enum class call_syntax { dot = 0, colon = 1 }; enum class call_status : int { ok = LUA_OK, yielded = LUA_YIELD, runtime = LUA_ERRRUN, memory = LUA_ERRMEM, handler = LUA_ERRERR, gc = LUA_ERRGCMM }; enum class thread_status : int { ok = LUA_OK, yielded = LUA_YIELD, runtime = LUA_ERRRUN, memory = LUA_ERRMEM, gc = LUA_ERRGCMM, handler = LUA_ERRERR, dead, }; enum class load_status : int { ok = LUA_OK, syntax = LUA_ERRSYNTAX, memory = LUA_ERRMEM, gc = LUA_ERRGCMM, file = LUA_ERRFILE, }; enum class type : int { none = LUA_TNONE, nil = LUA_TNIL, string = LUA_TSTRING, number = LUA_TNUMBER, thread = LUA_TTHREAD, boolean = LUA_TBOOLEAN, function = LUA_TFUNCTION, userdata = LUA_TUSERDATA, lightuserdata = LUA_TLIGHTUSERDATA, table = LUA_TTABLE, poly = none | nil | string | number | thread | table | boolean | function | userdata | lightuserdata }; enum class meta_function { construct, index, new_index, mode, call, metatable, to_string, length, unary_minus, addition, subtraction, multiplication, division, modulus, power_of, involution = power_of, concatenation, equal_to, less_than, less_than_or_equal_to, garbage_collect, call_function = call, }; const std::array meta_variable_names = { { "__index", "__newindex", } }; const std::array meta_function_names = { { "new", "__index", "__newindex", "__mode", "__call", "__metatable", "__tostring", "__len", "__unm", "__add", "__sub", "__mul", "__div", "__mod", "__pow", "__concat", "__eq", "__lt", "__le", "__gc", } }; inline const std::string& name_of( meta_function mf ) { return meta_function_names[static_cast(mf)]; } inline type type_of(lua_State* L, int index) { return static_cast(lua_type(L, index)); } inline int type_panic(lua_State* L, int index, type expected, type actual) { return luaL_error(L, "stack index %d, expected %s, received %s", index, expected == type::poly ? "anything" : lua_typename(L, static_cast(expected)), expected == type::poly ? "anything" : lua_typename(L, static_cast(actual)) ); } // Specify this function as the handler for lua::check if you know there's nothing wrong inline int no_panic(lua_State*, int, type, type) noexcept { return 0; } inline void type_error(lua_State* L, int expected, int actual) { luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual)); } inline void type_error(lua_State* L, type expected, type actual) { type_error(L, static_cast(expected), static_cast(actual)); } inline void type_assert(lua_State* L, int index, type expected, type actual) { if (expected != type::poly && expected != actual) { type_panic(L, index, expected, actual); } } inline void type_assert(lua_State* L, int index, type expected) { type actual = type_of(L, index); type_assert(L, index, expected, actual); } inline std::string type_name(lua_State* L, type t) { return lua_typename(L, static_cast(t)); } class reference; class stack_reference; template class usertype; template class basic_table_core; template using table_core = basic_table_core; template using stack_table_core = basic_table_core; typedef table_core table; typedef table_core global_table; typedef stack_table_core stack_table; typedef stack_table_core stack_global_table; template class basic_function; template class basic_protected_function; using function = basic_function; using protected_function = basic_protected_function; using stack_function = basic_function; using stack_protected_function = basic_protected_function; template class basic_object; template class basic_userdata; template class basic_lightuserdata; struct variadic_args; using object = basic_object; using stack_object = basic_object; using userdata = basic_userdata; using stack_userdata = basic_userdata; using lightuserdata = basic_lightuserdata; using stack_lightuserdata = basic_lightuserdata; class coroutine; class thread; struct variadic_args; struct this_state; template struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant { }; template <> struct lua_type_of : std::integral_constant { }; template <> struct lua_type_of : std::integral_constant { }; template struct lua_type_of> : std::integral_constant { }; template <> struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template struct lua_type_of> : std::integral_constant{}; template struct lua_type_of> : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template struct lua_type_of : std::integral_constant {}; template struct lua_type_of::value>> : std::integral_constant {}; template struct lua_type_of::value>> : std::integral_constant {}; template <> struct lua_type_of : std::integral_constant {}; template struct is_lua_primitive : std::integral_constant>::value || std::is_base_of>::value || std::is_base_of>::value || meta::is_specialization_of>::value || meta::is_specialization_of>::value > { }; template struct is_lua_primitive> : std::true_type { }; template struct is_lua_primitive> : std::true_type {}; template struct is_lua_primitive : std::true_type {}; template <> struct is_lua_primitive : std::true_type {}; template <> struct is_lua_primitive : std::true_type {}; template struct is_lua_primitive> : is_lua_primitive {}; template struct is_proxy_primitive : is_lua_primitive { }; template struct is_unique_usertype : std::integral_constant::value> {}; template struct is_transparent_argument : std::false_type {}; template <> struct is_transparent_argument : std::true_type {}; template <> struct is_transparent_argument : std::true_type {}; template inline type type_of() { return lua_type_of>::value; } } // sol #endif // SOL_TYPES_HPP