// 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 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 nil_t {}; const nil_t nil {}; inline bool operator==(nil_t, nil_t) { return true; } inline bool operator!=(nil_t, nil_t) { return false; } typedef std::add_lvalue_reference_t> lua_r_CFunction; template struct unique_usertype {}; 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 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) {} }; 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 { normal = LUA_OK, yielded = LUA_YIELD, error_runtime = LUA_ERRRUN, error_memory = LUA_ERRMEM, error_gc = LUA_ERRGCMM, error_handler = LUA_ERRERR, dead, }; 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 }; 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) { int actual = lua_type(L, index); if(expected != type::poly && static_cast(expected) != actual) { type_error(L, static_cast(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 table_core; typedef table_core table; typedef table_core global_table; class function; class protected_function; class coroutine; class thread; class object; class userdata; class lightuserdata; 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 is_lua_primitive : std::integral_constant>::value || std::is_base_of>::value || meta::is_specialization_of, std::tuple>::value || meta::is_specialization_of, std::pair>::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> : is_lua_primitive {}; template struct is_proxy_primitive : is_lua_primitive { }; template struct is_proxy_primitive> : std::true_type { }; template struct is_proxy_primitive> : std::true_type {}; template struct is_unique_usertype : std::false_type {}; template inline type type_of() { return lua_type_of>::value; } inline type type_of(lua_State* L, int index) { return static_cast(lua_type(L, index)); } } // sol #endif // SOL_TYPES_HPP