diff --git a/sol/error_handler.hpp b/sol/error_handler.hpp index 6842f7da..ad3bd532 100644 --- a/sol/error_handler.hpp +++ b/sol/error_handler.hpp @@ -23,6 +23,7 @@ #define SOL_ERROR_HANDLER_HPP #include "types.hpp" +#include "demangle.hpp" namespace sol { diff --git a/sol/simple_usertype_metatable.hpp b/sol/simple_usertype_metatable.hpp index fe5d91d1..e9215c85 100644 --- a/sol/simple_usertype_metatable.hpp +++ b/sol/simple_usertype_metatable.hpp @@ -65,7 +65,7 @@ namespace sol { } } } - string_detail::string_shim accessor = stack::get(L, keyidx); + string_view accessor = stack::get(L, keyidx); std::string accessorkey = accessor.data(); auto vit = variables.find(accessorkey); if (vit != variables.cend()) { diff --git a/sol/stack.hpp b/sol/stack.hpp index 13d13e56..18af8a22 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -210,7 +210,7 @@ namespace sol { return call_syntax::colon; } - inline void script(lua_State* L, const string_detail::string_shim& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { + inline void script(lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { char basechunkname[17] = {}; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) { diff --git a/sol/stack_get.hpp b/sol/stack_get.hpp index 7ac70f06..a7ae7400 100644 --- a/sol/stack_get.hpp +++ b/sol/stack_get.hpp @@ -422,6 +422,16 @@ namespace sol { } }; + template<> + struct getter { + static string_view get(lua_State* L, int index, record& tracking) { + tracking.use(1); + size_t sz; + const char* str = lua_tolstring(L, index, &sz); + return string_view(str, sz); + } + }; + #ifdef SOL_CODECVT_SUPPORT template<> struct getter { @@ -725,16 +735,6 @@ namespace sol { }; #ifdef SOL_CXX17_FEATURES - template<> - struct getter { - static std::string_view get(lua_State* L, int index, record& tracking) { - tracking.use(1); - size_t sz; - const char* str = lua_tolstring(L, index, &sz); - return std::string_view(str, sz); - } - }; - template struct getter> { typedef std::variant V; @@ -770,16 +770,6 @@ namespace sol { return get_one(std::integral_constant(), L, index, tracking); } }; -#else - template <> - struct getter { - string_detail::string_shim get(lua_State* L, int index, record& tracking) { - tracking.use(1); - size_t len; - const char* p = lua_tolstring(L, index, &len); - return string_detail::string_shim(p, len); - } - }; #endif // C++17-wave } // stack diff --git a/sol/stack_push.hpp b/sol/stack_push.hpp index e012392c..962f72f8 100644 --- a/sol/stack_push.hpp +++ b/sol/stack_push.hpp @@ -567,6 +567,13 @@ namespace sol { } }; + template <> + struct pusher { + static int push(lua_State* L, const string_view& sv) { + return stack::push(L, sv.data(), sv.length()); + } + }; + template<> struct pusher { static int push(lua_State* L, meta_function m) { @@ -756,6 +763,27 @@ namespace sol { return stack::push(L, u32str.data(), u32str.data() + sz); } }; + + template <> + struct pusher { + static int push(lua_State* L, const wstring_view& sv) { + return stack::push(L, sv.data(), sv.length()); + } + }; + + template <> + struct pusher { + static int push(lua_State* L, const u16string_view& sv) { + return stack::push(L, sv.data(), sv.length()); + } + }; + + template <> + struct pusher { + static int push(lua_State* L, const u32string_view& sv) { + return stack::push(L, sv.data(), sv.length()); + } + }; #endif // codecvt Header Support template @@ -826,35 +854,6 @@ namespace sol { }; #ifdef SOL_CXX17_FEATURES - template <> - struct pusher { - static int push(lua_State* L, const std::string_view& sv) { - return stack::push(L, sv.data(), sv.length()); - } - }; -#ifdef SOL_CODECVT_SUPPORT - template <> - struct pusher { - static int push(lua_State* L, const std::wstring_view& sv) { - return stack::push(L, sv.data(), sv.length()); - } - }; - - template <> - struct pusher { - static int push(lua_State* L, const std::u16string_view& sv) { - return stack::push(L, sv.data(), sv.length()); - } - }; - - template <> - struct pusher { - static int push(lua_State* L, const std::u32string_view& sv) { - return stack::push(L, sv.data(), sv.length()); - } - }; -#endif // codecvt header support - namespace stack_detail { struct push_function { @@ -880,18 +879,9 @@ namespace sol { return std::visit(stack_detail::push_function(L), std::move(v)); } }; -#else - template <> - struct pusher { - static int push(lua_State* L, const std::string_view& sv) { - return stack::push(L, sv.data(), sv.length()); - } - - static int push(lua_State* L, const std::string_view& sv, std::size_t len) { - return stack::push(L, sv.data(), len); - } - }; #endif // C++17 Support + + } // stack } // sol diff --git a/sol/state.hpp b/sol/state.hpp index 33e3cd80..d8415a66 100644 --- a/sol/state.hpp +++ b/sol/state.hpp @@ -47,15 +47,15 @@ namespace sol { inline int default_traceback_error_handler(lua_State*L) { using namespace sol; std::string msg = "An unknown error has triggered the default error handler"; - optional maybetopmsg = stack::check_get(L, 1); + optional maybetopmsg = stack::check_get(L, 1); if (maybetopmsg) { - const string_detail::string_shim& topmsg = maybetopmsg.value(); + const string_view& topmsg = maybetopmsg.value(); msg.assign(topmsg.data(), topmsg.size()); } luaL_traceback(L, L, msg.c_str(), 1); - optional maybetraceback = stack::check_get(L, -1); + optional maybetraceback = stack::check_get(L, -1); if (maybetraceback) { - const string_detail::string_shim& traceback = maybetraceback.value(); + const string_view& traceback = maybetraceback.value(); msg.assign(traceback.data(), traceback.size()); } return stack::push(L, msg); diff --git a/sol/string_shim.hpp b/sol/string_shim.hpp deleted file mode 100644 index bd3fbb43..00000000 --- a/sol/string_shim.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// The MIT License (MIT) - -// Copyright (c) 2013-2017 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_STRING_SHIM_HPP -#define SOL_STRING_SHIM_HPP - -#include "feature_test.hpp" -#include -#include -#ifdef SOL_CXX17_FEATURES -#include -#endif // C++17 features - -namespace sol { - namespace string_detail { -#ifdef SOL_CXX17_FEATURES - typedef std::string_view string_shim; -#else - struct string_shim { - std::size_t s; - const char* p; - - string_shim(const std::string& r) : string_shim(r.data(), r.size()) {} - string_shim(const char* ptr) : string_shim(ptr, std::char_traits::length(ptr)) {} - string_shim(const char* ptr, std::size_t sz) : s(sz), p(ptr) {} - - static int compare(const char* lhs_p, std::size_t lhs_sz, const char* rhs_p, std::size_t rhs_sz) { - int result = std::char_traits::compare(lhs_p, rhs_p, lhs_sz < rhs_sz ? lhs_sz : rhs_sz); - if (result != 0) - return result; - if (lhs_sz < rhs_sz) - return -1; - if (lhs_sz > rhs_sz) - return 1; - return 0; - } - - const char* begin() const { - return p; - } - - const char* end() const { - return p + s; - } - - const char* cbegin() const { - return p; - } - - const char* cend() const { - return p + s; - } - - const char* data() const { - return p; - } - - std::size_t size() const { - return s; - } - - bool operator==(const string_shim& r) const { - return compare(p, s, r.data(), r.size()) == 0; - } - - bool operator==(const char* r) const { - return compare(r, std::char_traits::length(r), p, s) == 0; - } - - bool operator==(const std::string& r) const { - return compare(r.data(), r.size(), p, s) == 0; - } - - bool operator!=(const string_shim& r) const { - return !(*this == r); - } - - bool operator!=(const char* r) const { - return !(*this == r); - } - - bool operator!=(const std::string& r) const { - return !(*this == r); - } - }; -#endif // C++17 - } - - typedef string_detail::string_shim string_view; -} - -#endif // SOL_STRING_SHIM_HPP diff --git a/sol/string_view.hpp b/sol/string_view.hpp new file mode 100644 index 00000000..a07637b3 --- /dev/null +++ b/sol/string_view.hpp @@ -0,0 +1,119 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2017 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_STRING_VIEW_HPP +#define SOL_STRING_VIEW_HPP + +#include "feature_test.hpp" +#include +#include +#ifdef SOL_CXX17_FEATURES +#include +#endif // C++17 features + +namespace sol { +#ifdef SOL_CXX17_FEATURES + typedef std::string_view string_view; + typedef std::wstring_view wstring_view; + typedef std::u16string_view u16string_view; + typedef std::u32string_view u32string_view; +#else + template > + struct basic_string_view { + std::size_t s; + const Char* p; + + basic_string_view(const std::string& r) : basic_string_view(r.data(), r.size()) {} + basic_string_view(const Char* ptr) : basic_string_view(ptr, Traits::length(ptr)) {} + basic_string_view(const Char* ptr, std::size_t sz) : s(sz), p(ptr) {} + + static int compare(const Char* lhs_p, std::size_t lhs_sz, const Char* rhs_p, std::size_t rhs_sz) { + int result = Traits::compare(lhs_p, rhs_p, lhs_sz < rhs_sz ? lhs_sz : rhs_sz); + if (result != 0) + return result; + if (lhs_sz < rhs_sz) + return -1; + if (lhs_sz > rhs_sz) + return 1; + return 0; + } + + const Char* begin() const { + return p; + } + + const Char* end() const { + return p + s; + } + + const Char* cbegin() const { + return p; + } + + const Char* cend() const { + return p + s; + } + + const Char* data() const { + return p; + } + + std::size_t size() const { + return s; + } + + std::size_t length() const { + return size(); + } + + bool operator==(const basic_string_view& r) const { + return compare(p, s, r.data(), r.size()) == 0; + } + + bool operator==(const Char* r) const { + return compare(r, std::char_traits::length(r), p, s) == 0; + } + + bool operator==(const std::basic_string& r) const { + return compare(r.data(), r.size(), p, s) == 0; + } + + bool operator!=(const basic_string_view& r) const { + return !(*this == r); + } + + bool operator!=(const char* r) const { + return !(*this == r); + } + + bool operator!=(const std::basic_string& r) const { + return !(*this == r); + } + }; + + using string_view = basic_string_view; + using wstring_view = basic_string_view; + using u16string_view = basic_string_view; + using u32string_view = basic_string_view; +#endif // C++17 Support +} + +#endif // SOL_STRING_VIEW_HPP diff --git a/sol/types.hpp b/sol/types.hpp index 551b540f..c06cb915 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -28,7 +28,7 @@ #include "forward.hpp" #include "forward_detail.hpp" #include "traits.hpp" -#include "string_shim.hpp" +#include "string_view.hpp" #include "raii.hpp" #include "filters.hpp" @@ -890,24 +890,21 @@ namespace sol { 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 {}; + #ifdef SOL_CXX17_FEATURES - 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 {}; -#else - template <> - struct lua_type_of : std::integral_constant {}; #endif // C++ 17 (or not) features template diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp index 3901945b..6a8d89c1 100644 --- a/sol/usertype_metatable.hpp +++ b/sol/usertype_metatable.hpp @@ -50,7 +50,7 @@ namespace sol { const int index_function_index = 3; const int newindex_function_index = 4; - typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&); + typedef void(*base_walk)(lua_State*, bool&, int&, string_view&); typedef int(*member_search)(lua_State*, void*, int); struct call_information { @@ -128,7 +128,7 @@ namespace sol { namespace usertype_detail { const lua_Integer toplevel_magic = static_cast(0xCCC2CCC1); - inline int is_indexer(string_detail::string_shim s) { + inline int is_indexer(string_view s) { if (s == to_string(meta_function::index)) { return 1; } @@ -156,31 +156,31 @@ namespace sol { return 0; } - inline auto make_shim(string_detail::string_shim s) { + inline auto make_string_view(string_view s) { return s; } - inline auto make_shim(call_construction) { - return string_detail::string_shim(to_string(meta_function::call_function)); + inline auto make_string_view(call_construction) { + return string_view(to_string(meta_function::call_function)); } - inline auto make_shim(meta_function mf) { - return string_detail::string_shim(to_string(mf)); + inline auto make_string_view(meta_function mf) { + return string_view(to_string(mf)); } - inline auto make_shim(base_classes_tag) { - return string_detail::string_shim(detail::base_class_cast_key()); + inline auto make_string_view(base_classes_tag) { + return string_view(detail::base_class_cast_key()); } template inline std::string make_string(Arg&& arg) { - string_detail::string_shim s = make_shim(arg); + string_view s = make_string_view(arg); return std::string(s.data(), s.size()); } template inline luaL_Reg make_reg(N&& n, lua_CFunction f) { - luaL_Reg l{ make_shim(std::forward(n)).data(), f }; + luaL_Reg l{ make_string_view(std::forward(n)).data(), f }; return l; } @@ -227,8 +227,8 @@ namespace sol { #endif } else { - auto maybeaccessor = stack::get>(L, is_index ? -1 : -2); - string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)")); + auto maybeaccessor = stack::get>(L, is_index ? -1 : -2); + string_view accessor = maybeaccessor.value_or(string_view("(unknown)")); return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data()); } } @@ -325,7 +325,7 @@ namespace sol { } template - static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) { + static void walk_single_base(lua_State* L, bool& found, int& ret, string_view&) { if (found) return; const char* metakey = &usertype_traits::metatable()[0]; @@ -355,7 +355,7 @@ namespace sol { } template - static void walk_all_bases(lua_State* L, bool& found, int& ret, string_detail::string_shim& accessor) { + static void walk_all_bases(lua_State* L, bool& found, int& ret, string_view& accessor) { (void)L; (void)found; (void)ret; @@ -404,7 +404,7 @@ namespace sol { template >> = meta::enabler> lua_CFunction make_func() const { const auto& name = std::get(functions); - return (usertype_detail::make_shim(name) == "__newindex") ? &call : &call; + return (usertype_detail::make_string_view(name) == "__newindex") ? &call : &call; } static bool contains_variable() { @@ -558,7 +558,7 @@ namespace sol { const usertype_detail::member_search& member = is_index ? ci.index: ci.new_index; return (member)(L, static_cast(&f), ci.runtime_target); } - string_detail::string_shim accessor = name; + string_view accessor = name; int ret = 0; bool found = false; // Otherwise, we need to do propagating calls through the bases