From ffdff21487f9376a16d2419d87a551c9644f1a68 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Fri, 12 Aug 2016 12:30:18 -0400 Subject: [PATCH] Trying to be smart about shit, take 1. :B --- sol/stack_get.hpp | 88 +++++++++++++++++++++++++++++++++------------- sol/stack_push.hpp | 15 ++++++-- test_strings.cpp | 43 +++++++++++++--------- 3 files changed, 103 insertions(+), 43 deletions(-) diff --git a/sol/stack_get.hpp b/sol/stack_get.hpp index 28582d00..6e290767 100644 --- a/sol/stack_get.hpp +++ b/sol/stack_get.hpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include namespace sol { namespace stack { @@ -164,19 +166,7 @@ namespace sol { return lua_tostring(L, index); } }; - - template<> - struct getter { - static meta_function get(lua_State *L, int index, record& tracking) { - tracking.use(1); - const char* name = getter{}.get(L, index, tracking); - for (std::size_t i = 0; i < meta_function_names.size(); ++i) - if (meta_function_names[i] == name) - return static_cast(i); - return meta_function::construct; - } - }; - + template<> struct getter { static char get(lua_State* L, int index, record& tracking) { @@ -191,17 +181,45 @@ namespace sol { struct getter { static std::wstring get(lua_State* L, int index, record& tracking) { tracking.use(1); - return{}; + size_t len; + auto str = lua_tolstring(L, index, &len); + if (len < 1) + return std::wstring(); + if (sizeof(wchar_t) == 2) { + std::wstring_convert> convert; + std::wstring r = convert.from_bytes(str, str + len); + return r; + } + else if (sizeof(wchar_t) == 4) { + std::wstring_convert> convert; + std::wstring r = convert.from_bytes(str, str + len); + return r; + } + // ... Uh, what the fuck do I even do here? + std::wstring_convert> convert; + std::wstring r = convert.from_bytes(str, str + len); + return r; } }; -#if 0 - template<> struct getter { static std::u16string get(lua_State* L, int index, record& tracking) { tracking.use(1); - return{}; + size_t len; + auto str = lua_tolstring(L, index, &len); + if (len < 1) + return std::u16string(); +#ifdef _MSC_VER + std::wstring_convert, int16_t> convert; + auto intd = convert.from_bytes(str, str + len); + std::u16string r(intd.size(), '\0'); + std::memcpy(&r[0], intd.data(), intd.size() * sizeof(char16_t)); +#else + std::wstring_convert, char16_t> convert; + std::u16string r = convert.from_bytes(str, str + len); +#endif // VC++ is a shit + return r; } }; @@ -209,15 +227,27 @@ namespace sol { struct getter { static std::u32string get(lua_State* L, int index, record& tracking) { tracking.use(1); - return{}; + size_t len; + auto str = lua_tolstring(L, index, &len); + if (len < 1) + return std::u32string(); +#ifdef _MSC_VER + std::wstring_convert, int32_t> convert; + auto intd = convert.from_bytes(str, str + len); + std::u32string r(intd.size(), '\0'); + std::memcpy(&r[0], intd.data(), r.size() * sizeof(char32_t)); +#else + std::wstring_convert, char32_t> convert; + std::u32string r = convert.from_bytes(str, str + len); +#endif // VC++ is a shit + return r; } }; template<> struct getter { static wchar_t get(lua_State* L, int index, record& tracking) { - tracking.use(1); - auto str = getter{}.get(L, index); + auto str = getter{}.get(L, index, tracking); return str.size() > 0 ? str[0] : '\0'; } }; @@ -225,8 +255,7 @@ namespace sol { template<> struct getter { static char get(lua_State* L, int index, record& tracking) { - tracking.use(1); - auto str = getter{}.get(L, index); + auto str = getter{}.get(L, index, tracking); return str.size() > 0 ? str[0] : '\0'; } }; @@ -234,13 +263,22 @@ namespace sol { template<> struct getter { static char32_t get(lua_State* L, int index, record& tracking) { - tracking.use(1); - auto str = getter{}.get(L, index); + auto str = getter{}.get(L, index, tracking); return str.size() > 0 ? str[0] : '\0'; } }; -#endif // For a distant future + template<> + struct getter { + static meta_function get(lua_State *L, int index, record& tracking) { + tracking.use(1); + const char* name = getter{}.get(L, index, tracking); + for (std::size_t i = 0; i < meta_function_names.size(); ++i) + if (meta_function_names[i] == name) + return static_cast(i); + return meta_function::construct; + } + }; template<> struct getter { diff --git a/sol/stack_push.hpp b/sol/stack_push.hpp index f141422d..47ef1735 100644 --- a/sol/stack_push.hpp +++ b/sol/stack_push.hpp @@ -27,6 +27,7 @@ #include "optional.hpp" #include #include +#include namespace sol { namespace stack { @@ -411,8 +412,18 @@ namespace sol { } static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) { - std::wstring_convert> utf8_conv; - std::string u8str = utf8_conv.to_bytes(strb, stre); + if (sizeof(wchar_t) == 2) { + std::wstring_convert> convert; + std::string u8str = convert.to_bytes(strb, stre); + return stack::push(L, u8str); + } + else if (sizeof(wchar_t) == 4) { + std::wstring_convert> convert; + std::string u8str = convert.to_bytes(strb, stre); + return stack::push(L, u8str); + } + std::wstring_convert> convert; + std::string u8str = convert.to_bytes(strb, stre); return stack::push(L, u8str); } }; diff --git a/test_strings.cpp b/test_strings.cpp index 755e9fc1..1f26c010 100644 --- a/test_strings.cpp +++ b/test_strings.cpp @@ -22,8 +22,16 @@ TEST_CASE("stack/strings", "test that strings can be roundtripped") { static const char utf8str[] = "\xF0\x9F\x8D\x8C\x20\xE6\x99\xA5\x20\x46\x6F\x6F\x20\xC2\xA9\x20\x62\x61\x72\x20\xF0\x9D\x8C\x86\x20\x62\x61\x7A\x20\xE2\x98\x83\x20\x71\x75\x78"; static const char16_t utf16str[] = { 0xD83C, 0xDF4C, 0x20, 0x6665, 0x20, 0x46, 0x6F, 0x6F, 0x20, 0xA9, 0x20, 0x62, 0x61, 0x72, 0x20, 0xD834, 0xDF06, 0x20, 0x62, 0x61, 0x7A, 0x20, 0x2603, 0x20, 0x71, 0x75, 0x78, 0x00 }; static const char32_t utf32str[] = { 0x1F34C, 0x0020, 0x6665, 0x0020, 0x0046, 0x006F, 0x006F, 0x0020, 0x00A9, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x1D306, 0x0020, 0x0062, 0x0061, 0x007A, 0x0020, 0x2603, 0x0020, 0x0071, 0x0075, 0x0078, 0x00 }; - static const wchar_t widestr[] = L"Fuck these shitty compilers"; - static const char32_t utf32str2[] = U"🕴"; +#ifdef _WIN32 + static const wchar_t widestr[] = { 0xD83C, 0xDF4C, 0x20, 0x6665, 0x20, 0x46, 0x6F, 0x6F, 0x20, 0xA9, 0x20, 0x62, 0x61, 0x72, 0x20, 0xD834, 0xDF06, 0x20, 0x62, 0x61, 0x7A, 0x20, 0x2603, 0x20, 0x71, 0x75, 0x78, 0x00 }; +#else + static const wchar_t widestr[] = { 0x1F34C, 0x0020, 0x6665, 0x0020, 0x0046, 0x006F, 0x006F, 0x0020, 0x00A9, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x1D306, 0x0020, 0x0062, 0x0061, 0x007A, 0x0020, 0x2603, 0x0020, 0x0071, 0x0075, 0x0078, 0x00 }; +#endif + static const std::string utf8str_s = utf8str; + static const std::u16string utf16str_s = utf16str; + static const std::u32string utf32str_s = utf32str; + static const std::wstring widestr_s = widestr; + lua["utf8"] = utf8str; lua["utf16"] = utf16str; @@ -35,36 +43,40 @@ TEST_CASE("stack/strings", "test that strings can be roundtripped") { std::string utf32_to_utf8 = lua["utf32"]; std::string wide_to_utf8 = lua["wide"]; - REQUIRE(utf8_to_utf8 == utf8str); - REQUIRE(utf16_to_utf8 == utf8str); - REQUIRE(utf32_to_utf8 == utf8str); - REQUIRE(wide_to_utf8 == utf8str); + REQUIRE(utf8_to_utf8 == utf8str_s); + REQUIRE(utf16_to_utf8 == utf8str_s); + REQUIRE(utf32_to_utf8 == utf8str_s); + REQUIRE(wide_to_utf8 == utf8str_s); std::wstring utf8_to_wide = lua["utf8"]; std::wstring utf16_to_wide = lua["utf16"]; std::wstring utf32_to_wide = lua["utf32"]; std::wstring wide_to_wide = lua["wide"]; - REQUIRE(utf8_to_wide == widestr); - REQUIRE(utf16_to_wide == widestr); - REQUIRE(utf32_to_wide == widestr); - REQUIRE(wide_to_wide == widestr); + REQUIRE(utf8_to_wide == widestr_s); + REQUIRE(utf16_to_wide == widestr_s); + REQUIRE(utf32_to_wide == widestr_s); + REQUIRE(wide_to_wide == widestr_s); -#if 0 std::u16string utf8_to_utf16 = lua["utf8"]; std::u16string utf16_to_utf16 = lua["utf16"]; std::u16string utf32_to_utf16 = lua["utf32"]; std::u16string wide_to_utf16 = lua["wide"]; + REQUIRE(utf8_to_utf16 == utf16str_s); + REQUIRE(utf16_to_utf16 == utf16str_s); + REQUIRE(utf32_to_utf16 == utf16str_s); + REQUIRE(wide_to_utf16 == utf16str_s); + std::u32string utf8_to_utf32 = lua["utf8"]; std::u32string utf16_to_utf32 = lua["utf16"]; std::u32string utf32_to_utf32 = lua["utf32"]; std::u32string wide_to_utf32 = lua["wide"]; - REQUIRE(utf8_to_utf32 == utf32str); - REQUIRE(utf16_to_utf32 == utf32str); - REQUIRE(utf32_to_utf32 == utf32str); - REQUIRE(wide_to_utf32 == utf32str); + REQUIRE(utf8_to_utf32 == utf32str_s); + REQUIRE(utf16_to_utf32 == utf32str_s); + REQUIRE(utf32_to_utf32 == utf32str_s); + REQUIRE(wide_to_utf32 == utf32str_s); char32_t utf8_to_char32 = lua["utf8"]; char32_t utf16_to_char32 = lua["utf16"]; @@ -75,7 +87,6 @@ TEST_CASE("stack/strings", "test that strings can be roundtripped") { REQUIRE(utf16_to_char32 == utf32str[0]); REQUIRE(utf32_to_char32 == utf32str[0]); REQUIRE(wide_to_char32 == utf32str[0]); -#endif // Shit C++ } TEST_CASE("detail/demangling", "test some basic demangling cases") {