// sol2 // The MIT License (MIT) // Copyright (c) 2013-2018 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 "error.hpp" #include "optional.hpp" #include "compatibility.hpp" #include "forward.hpp" #include "forward_detail.hpp" #include "traits.hpp" #include "string_view.hpp" #include "raii.hpp" #include "filters.hpp" #include #include #include #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES #include #ifdef SOL_STD_VARIANT #include #endif #endif // C++17 #ifdef SOL_USE_BOOST #include #else #include #endif // Using Boost namespace sol { namespace usertype_detail { #if defined(SOL_USE_BOOST) #if defined(SOL_CXX17_FEATURES) template , typename E = std::equal_to<>> using map_t = boost::unordered_map; #else template , typename E = std::equal_to<>> using map_t = boost::unordered_map; #endif // C++17 or not, WITH boost #else template , typename E = std::equal_to<>> using map_t = std::unordered_map; #endif // Boost map target } namespace detail { #ifdef SOL_NOEXCEPT_FUNCTION_TYPE typedef int(*lua_CFunction_noexcept)(lua_State* L) noexcept; #else typedef int(*lua_CFunction_noexcept)(lua_State* L); #endif // noexcept function type for lua_CFunction template struct unique_usertype {}; template struct implicit_wrapper { T& item; implicit_wrapper(T* item) : item(*item) { } implicit_wrapper(T& item) : item(item) { } operator T&() { return item; } operator T*() { return std::addressof(item); } }; struct unchecked_t {}; const unchecked_t unchecked = unchecked_t{}; struct yield_tag_t {}; const yield_tag_t yield_tag = yield_tag_t{}; } // namespace detail struct lua_nil_t {}; const lua_nil_t lua_nil{}; inline bool operator==(lua_nil_t, lua_nil_t) { return true; } inline bool operator!=(lua_nil_t, lua_nil_t) { return false; } typedef lua_nil_t nil_t; #if !defined(SOL_NO_NIL) || (SOL_NO_NIL == 0) const nil_t nil{}; #endif namespace detail { struct non_lua_nil_t {}; } struct metatable_t {}; const metatable_t metatable_key = {}; struct env_t {}; const env_t env_key = {}; struct no_metatable_t {}; const no_metatable_t no_metatable = {}; template struct yielding_t { T func; yielding_t() = default; yielding_t(const yielding_t&) = default; yielding_t(yielding_t&&) = default; yielding_t& operator=(const yielding_t&) = default; yielding_t& operator=(yielding_t&&) = default; template , yielding_t>>, meta::neg>>> = meta::enabler> yielding_t(Arg&& arg) : func(std::forward(arg)) { } template yielding_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : func(std::forward(arg0), std::forward(arg1), std::forward(args)...) { } }; template inline yielding_t> yielding(F&& f) { return yielding_t>(std::forward(f)); } typedef std::remove_pointer_t lua_CFunction_ref; template struct unique_usertype_traits { typedef T type; typedef T actual_type; template using base_id = void; 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; // rebind is non-void // and tag is a unique integer // if and only if unique usertype // is cast-capable using base_id = std::shared_ptr; static const bool value = true; static bool is_null(const actual_type& p) { return p == 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; template using base_id = void; static const bool value = true; static bool is_null(const actual_type& p) { return p == nullptr; } static type* get(const actual_type& p) { return p.get(); } }; template struct non_null {}; template struct function_sig {}; struct upvalue_index { int index; upvalue_index(int idx) : index(lua_upvalueindex(idx)) { } operator int() const { return index; } }; struct raw_index { int index; raw_index(int i) : index(i) { } 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 ref_index { int index; ref_index(int idx) : index(idx) { } operator int() const { return index; } }; struct stack_count { int count; stack_count(int cnt) : count(cnt) { } }; struct lightuserdata_value { void* value; lightuserdata_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; } }; template struct light { L* value; light(L& x) : value(std::addressof(x)) { } light(L* x) : value(x) { } light(void* x) : value(static_cast(x)) { } operator L*() const { return value; } operator L&() const { return *value; } }; template auto make_light(T& l) { typedef meta::unwrapped_t>> L; return light(l); } template struct user { U value; user(U&& x) : value(std::forward(x)) { } operator std::add_pointer_t>() { return std::addressof(value); } operator std::add_lvalue_reference_t() { return value; } operator std::add_const_t>&() const { return value; } }; template auto make_user(T&& u) { typedef meta::unwrapped_t> U; return user(std::forward(u)); } template struct metatable_registry_key { T key; metatable_registry_key(T key) : key(std::forward(key)) { } }; template auto meta_registry_key(T&& key) { typedef meta::unqualified_t K; return metatable_registry_key(std::forward(key)); } template struct closure { lua_CFunction c_function; std::tuple upvalues; closure(lua_CFunction f, Upvalues... targetupvalues) : c_function(f), upvalues(std::forward(targetupvalues)...) { } }; template <> struct closure<> { lua_CFunction c_function; int upvalues; closure(lua_CFunction f, int upvalue_count = 0) : c_function(f), upvalues(upvalue_count) { } }; typedef closure<> c_closure; template closure make_closure(lua_CFunction f, Args&&... args) { return closure(f, std::forward(args)...); } template struct function_arguments { std::tuple arguments; template , function_arguments>> = meta::enabler> function_arguments(Arg&& arg, Args&&... args) : arguments(std::forward(arg), std::forward(args)...) { } }; template , typename... Args> auto as_function(Args&&... args) { return function_arguments...>(std::forward(args)...); } template , typename... Args> auto as_function_reference(Args&&... args) { return function_arguments(std::forward(args)...); } template struct as_table_t { T source; as_table_t() = default; as_table_t(const as_table_t&) = default; as_table_t(as_table_t&&) = default; as_table_t& operator=(const as_table_t&) = default; as_table_t& operator=(as_table_t&&) = default; template , as_table_t>>, meta::neg>>> = meta::enabler> as_table_t(Arg&& arg) : source(std::forward(arg)) { } template as_table_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : source(std::forward(arg0), std::forward(arg1), std::forward(args)...) { } operator std::add_lvalue_reference_t() { return source; } }; template struct nested { T source; nested() = default; nested(const nested&) = default; nested(nested&&) = default; nested& operator=(const nested&) = default; nested& operator=(nested&&) = default; template , nested>>, meta::neg>>> = meta::enabler> nested(Arg&& arg) : source(std::forward(arg)) { } template nested(Arg0&& arg0, Arg1&& arg1, Args&&... args) : source(std::forward(arg0), std::forward(arg1), std::forward(args)...) { } operator std::add_lvalue_reference_t() { return source; } }; template as_table_t as_table_ref(T&& container) { return as_table_t(std::forward(container)); } template as_table_t> as_table(T&& container) { return as_table_t>(std::forward(container)); } template nested as_nested_ref(T&& container) { return nested(std::forward(container)); } template nested> as_nested(T&& container) { return nested>(std::forward(container)); } struct this_state { lua_State* L; this_state(lua_State* Ls) : L(Ls) { } operator lua_State*() const noexcept { return lua_state(); } lua_State* operator->() const noexcept { return lua_state(); } lua_State* lua_state() const noexcept { return L; } }; struct this_main_state { lua_State* L; this_main_state(lua_State* Ls) : L(Ls) { } operator lua_State*() const noexcept { return lua_state(); } lua_State* operator->() const noexcept { return lua_state(); } lua_State* lua_state() const noexcept { return L; } }; struct new_table { int sequence_hint = 0; int map_hint = 0; new_table() = default; new_table(const new_table&) = default; new_table(new_table&&) = default; new_table& operator=(const new_table&) = default; new_table& operator=(new_table&&) = default; new_table(int sequence_hint, int map_hint = 0) : sequence_hint(sequence_hint), map_hint(map_hint) { } }; enum class lib : char { // print, assert, and other base functions base, // require and other package functions package, // coroutine functions and utilities coroutine, // string library string, // functionality from the OS os, // all things math math, // the table manipulator and observer functions table, // the debug library debug, // the bit library: different based on which you're using bit32, // input/output library io, // LuaJIT only ffi, // LuaJIT only jit, // library for handling utf8: new to Lua utf8, // do not use count }; enum class call_syntax { dot = 0, colon = 1 }; enum class load_mode { any = 0, text = 1, binary = 2, }; enum class call_status : int { ok = LUA_OK, yielded = LUA_YIELD, runtime = LUA_ERRRUN, memory = LUA_ERRMEM, handler = LUA_ERRERR, gc = LUA_ERRGCMM, syntax = LUA_ERRSYNTAX, file = LUA_ERRFILE, }; enum class thread_status : int { ok = LUA_OK, yielded = LUA_YIELD, runtime = LUA_ERRRUN, memory = LUA_ERRMEM, gc = LUA_ERRGCMM, handler = LUA_ERRERR, dead = -1, }; 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, lua_nil = LUA_TNIL, #if !defined(SOL_NO_NIL) nil = lua_nil, #endif // Objective C/C++ Keyword that's found in OSX SDK and OBJC -- check for all forms to protect 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 = -0xFFFF }; inline const std::string& to_string(call_status c) { static const std::array names{ { "ok", "yielded", "runtime", "memory", "handler", "gc", "syntax", "file", "CRITICAL_EXCEPTION_FAILURE", "CRITICAL_INDETERMINATE_STATE_FAILURE" } }; switch (c) { case call_status::ok: return names[0]; case call_status::yielded: return names[1]; case call_status::runtime: return names[2]; case call_status::memory: return names[3]; case call_status::handler: return names[4]; case call_status::gc: return names[5]; case call_status::syntax: return names[6]; case call_status::file: return names[7]; } if (static_cast(c) == -1) { // One of the many cases where a critical exception error has occurred return names[8]; } return names[9]; } inline bool is_indeterminate_call_failure(call_status c) { switch (c) { case call_status::ok: case call_status::yielded: case call_status::runtime: case call_status::memory: case call_status::handler: case call_status::gc: case call_status::syntax: case call_status::file: return false; } return true; } inline const std::string& to_string(load_status c) { static const std::array names{ { "ok", "memory", "gc", "syntax", "file", "CRITICAL_EXCEPTION_FAILURE", "CRITICAL_INDETERMINATE_STATE_FAILURE" } }; switch (c) { case load_status::ok: return names[0]; case load_status::memory: return names[1]; case load_status::gc: return names[2]; case load_status::syntax: return names[3]; case load_status::file: return names[4]; } if (static_cast(c) == -1) { // One of the many cases where a critical exception error has occurred return names[5]; } return names[6]; } inline const std::string& to_string(load_mode c) { static const std::array names{ { "bt", "t", "b", } }; return names[static_cast(c)]; } enum class meta_function { construct, index, new_index, mode, call, call_function = 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, floor_division, bitwise_left_shift, bitwise_right_shift, bitwise_not, bitwise_and, bitwise_or, bitwise_xor, pairs, ipairs, next, type, type_info, }; typedef meta_function meta_method; inline const std::array& meta_function_names() { static const std::array names = { { "new", "__index", "__newindex", "__mode", "__call", "__mt", "__tostring", "__len", "__unm", "__add", "__sub", "__mul", "__div", "__mod", "__pow", "__concat", "__eq", "__lt", "__le", "__gc", "__idiv", "__shl", "__shr", "__bnot", "__band", "__bor", "__bxor", "__pairs", "__ipairs", "next", "__type", "__typeinfo" } }; return names; } inline const std::string& to_string(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 std::string type_name(lua_State* L, type t) { return lua_typename(L, static_cast(t)); } template struct is_lua_reference : std::integral_constant>::value || std::is_base_of>::value || std::is_base_of>::value> {}; template struct is_lua_reference_or_proxy : std::integral_constant>::value || meta::is_specialization_of, proxy>::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 <> struct is_transparent_argument : std::true_type {}; template <> struct is_transparent_argument : std::true_type {}; template struct is_variadic_arguments : std::is_same, variadic_args> {}; namespace detail { template struct is_initializer_list : std::false_type {}; template struct is_initializer_list> : std::true_type {}; template struct is_container : std::false_type {}; template struct is_container> : std::false_type {}; template struct is_container>::value>> : std::false_type {}; template struct is_container> , meta::neg>, char, wchar_t, char16_t, char32_t>> >::value >> : std::true_type {}; template struct is_container> , meta::neg>> , meta::neg>> >::value >> : std::true_type {}; } // namespace detail template struct is_container : detail::is_container {}; template struct is_to_stringable : meta::any>, meta::supports_adl_to_string>, meta::supports_ostream_op>> {}; namespace detail { 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 : 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 {}; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES #ifdef SOL_STD_VARIANT template struct lua_type_of> : std::integral_constant {}; #endif // SOL_STD_VARIANT #endif // SOL_CXX17_FEATURES template struct lua_type_of, std::enable_if_t<::sol::is_container::value>> : std::integral_constant {}; template struct lua_type_of, std::enable_if_t::value>> : lua_type_of {}; template class V, typename... Args> struct accumulate : std::integral_constant {}; template class V, typename T, typename... Args> struct accumulate : accumulate::value, V, Args...> {}; } // namespace detail template struct is_unique_usertype : std::integral_constant::value> {}; template struct lua_type_of : detail::lua_type_of { typedef int SOL_INTERNAL_UNSPECIALIZED_MARKER_; }; template struct lua_size : std::integral_constant { typedef int SOL_INTERNAL_UNSPECIALIZED_MARKER_; }; template struct lua_size> : std::integral_constant::value + lua_size::value> {}; template struct lua_size> : std::integral_constant::value> {}; namespace detail { template struct void_ { typedef void type; }; template struct has_internal_marker_impl : std::false_type {}; template struct has_internal_marker_impl::type> : std::true_type {}; template struct has_internal_marker : has_internal_marker_impl {}; } // namespace detail template struct is_lua_primitive : std::integral_constant>::value || ((type::userdata == lua_type_of>::value) && detail::has_internal_marker>>::value && !detail::has_internal_marker>>::value) || is_lua_reference>::value || meta::is_specialization_of, std::tuple>::value || meta::is_specialization_of, std::pair>::value> {}; template struct is_main_threaded : std::is_base_of {}; template struct is_stack_based : std::is_base_of {}; template <> struct is_stack_based : std::true_type {}; template <> struct is_stack_based : std::true_type {}; template <> struct is_stack_based : std::true_type {}; template <> struct is_stack_based : std::true_type {}; template <> struct is_stack_based : 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> : std::true_type {}; template struct is_lua_primitive> : is_lua_primitive {}; 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_lua_index : std::is_integral {}; template <> struct is_lua_index : std::true_type {}; template <> struct is_lua_index : std::true_type {}; template <> struct is_lua_index : std::true_type {}; template <> struct is_lua_index : std::true_type {}; template struct lua_bind_traits : meta::bind_traits { private: typedef meta::bind_traits base_t; public: typedef std::integral_constant::value != 0> runtime_variadics_t; static const std::size_t true_arity = base_t::arity; static const std::size_t arity = base_t::arity - meta::count_for::value; static const std::size_t true_free_arity = base_t::free_arity; static const std::size_t free_arity = base_t::free_arity - meta::count_for::value; }; template struct is_table : std::false_type {}; template struct is_table> : std::true_type {}; template struct is_function : std::false_type {}; template struct is_function> : std::true_type {}; template struct is_function> : std::true_type {}; template struct is_lightuserdata : std::false_type {}; template struct is_lightuserdata> : std::true_type {}; template struct is_userdata : std::false_type {}; template struct is_userdata> : std::true_type {}; template struct is_environment : std::integral_constant::value || is_table::value> {}; template struct is_automagical : std::true_type {}; template inline type type_of() { return lua_type_of>::value; } namespace detail { template struct is_non_factory_constructor : std::false_type {}; template struct is_non_factory_constructor> : std::true_type {}; template struct is_non_factory_constructor> : std::true_type {}; template <> struct is_non_factory_constructor : std::true_type {}; template struct is_constructor : is_non_factory_constructor {}; template struct is_constructor> : std::true_type {}; template struct is_constructor> : is_constructor> {}; template struct is_constructor> : is_constructor> {}; template using has_constructor = meta::any>...>; template struct is_destructor : std::false_type {}; template struct is_destructor> : std::true_type {}; template using has_destructor = meta::any>...>; struct add_destructor_tag {}; struct check_destructor_tag {}; struct verified_tag { } const verified{}; } // namespace detail } // namespace sol #endif // SOL_TYPES_HPP