fix GCC 11 compiler/libstdc++ error

GCC 11's C++ stdlib does a weird maneuver here where it needs to know
the size of the std::pair<>::second's type. So we wrap it in a ptr.
This commit is contained in:
Lion Kortlepel committed 2026-04-19 21:16:43 +00:00
1 parent 7c6acfdc86
commit 57fe7cb055
4 files changed
+56 -48

No files matched your search

+6 -1
View File
@@ -21,13 +21,18 @@
#include "Common.h" #include "Common.h"
#include <condition_variable> #include <condition_variable>
#include <string> #include <string>
#include <memory>
#include <sol/sol.hpp> #include <sol/sol.hpp>
using TLuaStateId = std::string; using TLuaStateId = std::string;
struct TDetachedLuaValue { struct TDetachedLuaValue {
using Ptr = std::shared_ptr<TDetachedLuaValue>;
using Array = std::vector<TDetachedLuaValue>; using Array = std::vector<TDetachedLuaValue>;
using Object = std::unordered_map<std::string, TDetachedLuaValue>; // 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::string, TDetachedLuaValue::Ptr>;
std::variant<std::monostate, bool, double, int, std::string, Array, Object> V; std::variant<std::monostate, bool, double, int, std::string, Array, Object> V;
}; };
std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value); std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value);
-40
View File
@@ -374,46 +374,6 @@ std::string GetPlatformAgnosticErrorString() {
return "(no human-readable errors on this platform)"; return "(no human-readable errors on this platform)";
#endif #endif
} }
std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value) {
std::visit([&os](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, TDetachedLuaValue::Array>) {
size_t i = 0;
for (auto val : arg) {
if (i > 0) {
os << ", ";
}
os << val;
++i;
}
} else if constexpr (std::is_same_v<T, TDetachedLuaValue::Object>) {
size_t i = 0;
for (auto [key, val] : arg) {
if (i > 0) {
os << ", ";
}
os << key << "=" << val;
++i;
}
} else if constexpr (std::is_same_v<T, bool>)
os << (arg ? "true" : "false");
else if constexpr (std::is_same_v<T, double>)
os << arg;
else if constexpr (std::is_same_v<T, int>)
os << arg;
else if constexpr (std::is_same_v<T, std::string>)
os << arg;
else if constexpr (std::is_same_v<T, std::monostate>)
// monostate means no result value
os << "";
else
static_assert(AlwaysFalseV<T>, "non-exhaustive visitor!");
},
value.V);
return os;
}
// TODO: add unit tests to SplitString // TODO: add unit tests to SplitString
void SplitString(const std::string& str, const char delim, std::vector<std::string>& out) { void SplitString(const std::string& str, const char delim, std::vector<std::string>& out) {
+2 -2
View File
@@ -554,9 +554,9 @@ sol::table TLuaEngine::StateThreadData::Lua_TriggerGlobalEvent(const std::string
auto Snapshot = Value->GetDetachedSnapshot(); auto Snapshot = Value->GetDetachedSnapshot();
std::visit([i, &Result](auto&& arg) { std::visit([i, &Result](auto&& arg) {
using T = std::decay_t<decltype(arg)>; using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::vector<TDetachedLuaValue>>) if constexpr (std::is_same_v<T, TDetachedLuaValue::Array>)
Result.set(i, arg); Result.set(i, arg);
else if constexpr (std::is_same_v<T, std::unordered_map<std::string, TDetachedLuaValue>>) else if constexpr (std::is_same_v<T, TDetachedLuaValue::Object>)
Result.set(i, arg); Result.set(i, arg);
else if constexpr (std::is_same_v<T, bool>) else if constexpr (std::is_same_v<T, bool>)
Result.set(i, arg); Result.set(i, arg);
+48 -5
View File
@@ -19,9 +19,52 @@
#include "TLuaResult.h" #include "TLuaResult.h"
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
#include <sol/unsafe_function_result.hpp>
#include <stdexcept> #include <stdexcept>
#include <thread> #include <thread>
std::ostream& operator<<(std::ostream& os, const TDetachedLuaValue& value) {
std::visit([&os](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, TDetachedLuaValue::Array>) {
size_t i = 0;
for (const auto& val : arg) {
if (i > 0) {
os << ", ";
}
os << val;
++i;
}
} else if constexpr (std::is_same_v<T, TDetachedLuaValue::Object>) {
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<T, bool>)
os << (arg ? "true" : "false");
else if constexpr (std::is_same_v<T, double>)
os << arg;
else if constexpr (std::is_same_v<T, int>)
os << arg;
else if constexpr (std::is_same_v<T, std::string>)
os << arg;
else if constexpr (std::is_same_v<T, std::monostate>)
// monostate means no result value
os << "";
else
static_assert(AlwaysFalseV<T>, "non-exhaustive visitor!");
},
value.V);
return os;
}
void TLuaResult::MarkReadySuccess(sol::object Res) { void TLuaResult::MarkReadySuccess(sol::object Res) {
std::unique_lock Lock(mMutex); std::unique_lock Lock(mMutex);
mError = false; mError = false;
@@ -116,7 +159,7 @@ TDetachedLuaValue TLuaResult::Freeze(const sol::object& o, int depth) {
for (auto&& [k, v] : o.as<sol::table>()) { for (auto&& [k, v] : o.as<sol::table>()) {
if (!k.is<std::string>()) if (!k.is<std::string>())
continue; // no numeric-key handling, don't need it continue; // no numeric-key handling, don't need it
out.emplace(k.as<std::string>(), Freeze(v, depth + 1)); out.emplace(k.as<std::string>(), std::make_shared<TDetachedLuaValue>(std::move(Freeze(v, depth + 1))));
} }
return { { std::move(out) } }; return { { std::move(out) } };
} }
@@ -199,18 +242,18 @@ TEST_CASE("TLuaResult detached snapshot freezes nested string-keyed tables") {
CHECK(object->contains("inner")); CHECK(object->contains("inner"));
CHECK_FALSE(object->contains("1")); CHECK_FALSE(object->contains("1"));
const auto* flag = std::get_if<bool>(&object->at("flag").V); const auto* flag = std::get_if<bool>(&object->at("flag")->V);
REQUIRE(flag != nullptr); REQUIRE(flag != nullptr);
CHECK(*flag); CHECK(*flag);
const auto* msg = std::get_if<std::string>(&object->at("msg").V); const auto* msg = std::get_if<std::string>(&object->at("msg")->V);
REQUIRE(msg != nullptr); REQUIRE(msg != nullptr);
CHECK(*msg == "hello"); CHECK(*msg == "hello");
const auto* innerObj = std::get_if<TDetachedLuaValue::Object>(&object->at("inner").V); const auto* innerObj = std::get_if<TDetachedLuaValue::Object>(&object->at("inner")->V);
REQUIRE(innerObj != nullptr); REQUIRE(innerObj != nullptr);
REQUIRE(innerObj->contains("k")); REQUIRE(innerObj->contains("k"));
const auto* innerValue = std::get_if<std::string>(&innerObj->at("k").V); const auto* innerValue = std::get_if<std::string>(&innerObj->at("k")->V);
REQUIRE(innerValue != nullptr); REQUIRE(innerValue != nullptr);
CHECK(*innerValue == "v"); CHECK(*innerValue == "v");
} }