diff --git a/include/TLuaResult.h b/include/TLuaResult.h index 18afb2e..a75da92 100644 --- a/include/TLuaResult.h +++ b/include/TLuaResult.h @@ -21,13 +21,18 @@ #include "Common.h" #include #include +#include #include using TLuaStateId = std::string; struct TDetachedLuaValue { + using Ptr = std::shared_ptr; using Array = std::vector; - using Object = std::unordered_map; + // This weird Ptr indirection is needed because some implementations of libstc++, + // like the GCC 11 one shipped with ubuntu 22.04, need to know the size of the second + // member of the pairs that make up the elements of such a map. It's fine in vector. + using Object = std::unordered_map; std::variant V; }; std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value); diff --git a/src/Common.cpp b/src/Common.cpp index be77275..1c769a3 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -374,46 +374,6 @@ std::string GetPlatformAgnosticErrorString() { return "(no human-readable errors on this platform)"; #endif } -std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value) { - - std::visit([&os](auto&& arg) { - using T = std::decay_t; - if constexpr (std::is_same_v) { - size_t i = 0; - for (auto val : arg) { - if (i > 0) { - os << ", "; - } - os << val; - ++i; - } - } else if constexpr (std::is_same_v) { - size_t i = 0; - for (auto [key, val] : arg) { - if (i > 0) { - os << ", "; - } - os << key << "=" << val; - ++i; - } - } else if constexpr (std::is_same_v) - os << (arg ? "true" : "false"); - else if constexpr (std::is_same_v) - os << arg; - else if constexpr (std::is_same_v) - os << arg; - else if constexpr (std::is_same_v) - os << arg; - else if constexpr (std::is_same_v) - // monostate means no result value - os << ""; - else - static_assert(AlwaysFalseV, "non-exhaustive visitor!"); - }, - value.V); - - return os; -} // TODO: add unit tests to SplitString void SplitString(const std::string& str, const char delim, std::vector& out) { diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index 84dd501..c0e3a28 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -554,9 +554,9 @@ sol::table TLuaEngine::StateThreadData::Lua_TriggerGlobalEvent(const std::string auto Snapshot = Value->GetDetachedSnapshot(); std::visit([i, &Result](auto&& arg) { using T = std::decay_t; - if constexpr (std::is_same_v>) + if constexpr (std::is_same_v) Result.set(i, arg); - else if constexpr (std::is_same_v>) + else if constexpr (std::is_same_v) Result.set(i, arg); else if constexpr (std::is_same_v) Result.set(i, arg); diff --git a/src/TLuaResult.cpp b/src/TLuaResult.cpp index a57d20e..39f4af6 100644 --- a/src/TLuaResult.cpp +++ b/src/TLuaResult.cpp @@ -19,9 +19,52 @@ #include "TLuaResult.h" #include #include +#include #include #include + +std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value) { + std::visit([&os](auto&& arg) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + size_t i = 0; + for (const auto& val : arg) { + if (i > 0) { + os << ", "; + } + os << val; + ++i; + } + } else if constexpr (std::is_same_v) { + size_t i = 0; + for (const auto& [key, val] : arg) { + if (i > 0) { + os << ", "; + } + os << key << "=" << val; + ++i; + } + } else if constexpr (std::is_same_v) + os << (arg ? "true" : "false"); + else if constexpr (std::is_same_v) + os << arg; + else if constexpr (std::is_same_v) + os << arg; + else if constexpr (std::is_same_v) + os << arg; + else if constexpr (std::is_same_v) + // monostate means no result value + os << ""; + else + static_assert(AlwaysFalseV, "non-exhaustive visitor!"); + }, + value.V); + + return os; +} + + void TLuaResult::MarkReadySuccess(sol::object Res) { std::unique_lock Lock(mMutex); mError = false; @@ -116,7 +159,7 @@ TDetachedLuaValue TLuaResult::Freeze(const sol::object& o, int depth) { for (auto&& [k, v] : o.as()) { if (!k.is()) continue; // no numeric-key handling, don't need it - out.emplace(k.as(), Freeze(v, depth + 1)); + out.emplace(k.as(), std::make_shared(std::move(Freeze(v, depth + 1)))); } return { { std::move(out) } }; } @@ -199,18 +242,18 @@ TEST_CASE("TLuaResult detached snapshot freezes nested string-keyed tables") { CHECK(object->contains("inner")); CHECK_FALSE(object->contains("1")); - const auto* flag = std::get_if(&object->at("flag").V); + const auto* flag = std::get_if(&object->at("flag")->V); REQUIRE(flag != nullptr); CHECK(*flag); - const auto* msg = std::get_if(&object->at("msg").V); + const auto* msg = std::get_if(&object->at("msg")->V); REQUIRE(msg != nullptr); CHECK(*msg == "hello"); - const auto* innerObj = std::get_if(&object->at("inner").V); + const auto* innerObj = std::get_if(&object->at("inner")->V); REQUIRE(innerObj != nullptr); REQUIRE(innerObj->contains("k")); - const auto* innerValue = std::get_if(&innerObj->at("k").V); + const auto* innerValue = std::get_if(&innerObj->at("k")->V); REQUIRE(innerValue != nullptr); CHECK(*innerValue == "v"); }