Trying to be smart about shit, take 1. :B

This commit is contained in:
ThePhD 2016-08-12 12:30:18 -04:00
parent 391152382c
commit ffdff21487
3 changed files with 103 additions and 43 deletions

View File

@ -30,6 +30,8 @@
#include <memory>
#include <functional>
#include <utility>
#include <codecvt>
#include <locale>
namespace sol {
namespace stack {
@ -164,19 +166,7 @@ namespace sol {
return lua_tostring(L, index);
}
};
template<>
struct getter<meta_function> {
static meta_function get(lua_State *L, int index, record& tracking) {
tracking.use(1);
const char* name = getter<const char*>{}.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<meta_function>(i);
return meta_function::construct;
}
};
template<>
struct getter<char> {
static char get(lua_State* L, int index, record& tracking) {
@ -191,17 +181,45 @@ namespace sol {
struct getter<std::wstring> {
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<std::codecvt_utf8_utf16<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len);
return r;
}
else if (sizeof(wchar_t) == 4) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len);
return r;
}
// ... Uh, what the fuck do I even do here?
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
std::wstring r = convert.from_bytes(str, str + len);
return r;
}
};
#if 0
template<>
struct getter<std::u16string> {
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<std::codecvt_utf8_utf16<int16_t>, 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<std::codecvt_utf8_utf16<char16_t>, 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<std::u32string> {
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<std::codecvt_utf8<int32_t>, 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<std::codecvt_utf8<char32_t>, char32_t> convert;
std::u32string r = convert.from_bytes(str, str + len);
#endif // VC++ is a shit
return r;
}
};
template<>
struct getter<wchar_t> {
static wchar_t get(lua_State* L, int index, record& tracking) {
tracking.use(1);
auto str = getter<std::wstring>{}.get(L, index);
auto str = getter<std::wstring>{}.get(L, index, tracking);
return str.size() > 0 ? str[0] : '\0';
}
};
@ -225,8 +255,7 @@ namespace sol {
template<>
struct getter<char16_t> {
static char get(lua_State* L, int index, record& tracking) {
tracking.use(1);
auto str = getter<std::u16string>{}.get(L, index);
auto str = getter<std::u16string>{}.get(L, index, tracking);
return str.size() > 0 ? str[0] : '\0';
}
};
@ -234,13 +263,22 @@ namespace sol {
template<>
struct getter<char32_t> {
static char32_t get(lua_State* L, int index, record& tracking) {
tracking.use(1);
auto str = getter<std::u32string>{}.get(L, index);
auto str = getter<std::u32string>{}.get(L, index, tracking);
return str.size() > 0 ? str[0] : '\0';
}
};
#endif // For a distant future
template<>
struct getter<meta_function> {
static meta_function get(lua_State *L, int index, record& tracking) {
tracking.use(1);
const char* name = getter<const char*>{}.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<meta_function>(i);
return meta_function::construct;
}
};
template<>
struct getter<nil_t> {

View File

@ -27,6 +27,7 @@
#include "optional.hpp"
#include <memory>
#include <codecvt>
#include <locale>
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<std::codecvt_utf8<wchar_t>> utf8_conv;
std::string u8str = utf8_conv.to_bytes(strb, stre);
if (sizeof(wchar_t) == 2) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
std::string u8str = convert.to_bytes(strb, stre);
return stack::push(L, u8str);
}
else if (sizeof(wchar_t) == 4) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
std::string u8str = convert.to_bytes(strb, stre);
return stack::push(L, u8str);
}
std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
std::string u8str = convert.to_bytes(strb, stre);
return stack::push(L, u8str);
}
};

View File

@ -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") {