Added support for map values and can_hold_type_v utility trait to ScriptValue.

This commit is contained in:
Patrick 2024-08-17 18:10:29 +02:00
parent bb05bb0ae5
commit 9337ad7ddb

View File

@ -6,6 +6,7 @@
#include <charconv> #include <charconv>
#include <string> #include <string>
#include <unordered_map>
#include <variant> #include <variant>
#include <vector> #include <vector>
@ -14,6 +15,16 @@
namespace mijin namespace mijin
{ {
//
// public traits
//
template<typename TSearch, typename TVariant>
inline constexpr bool variant_contains_v = false;
template<typename TSearch, typename... TVariantTypes>
inline constexpr bool variant_contains_v<TSearch, std::variant<TVariantTypes...>> = mijin::is_any_type_v<TSearch, TVariantTypes...>;
// //
// public types // public types
// //
@ -26,12 +37,12 @@ template<typename TScriptValue>
struct ArrayValue struct ArrayValue
{ {
std::vector<TScriptValue> values; std::vector<TScriptValue> values;
};
bool operator==(const ArrayValue& other) const; template<typename TScriptValue>
inline bool operator!=(const ArrayValue& other) const { struct MapValue
return !(*this == other); {
} std::unordered_map<std::string, TScriptValue> values;
std::partial_ordering operator<=>(const ArrayValue& other) const;
}; };
struct UndefinedValue struct UndefinedValue
@ -52,6 +63,7 @@ using script_value_base_t = std::variant<
script_float_t, script_float_t,
std::string, std::string,
ArrayValue<TConcrete>, ArrayValue<TConcrete>,
MapValue<TConcrete>,
TAdditional... TAdditional...
>; >;
@ -62,8 +74,12 @@ public:
using base_t = script_value_base_t<TConcrete, TAdditional...>; using base_t = script_value_base_t<TConcrete, TAdditional...>;
using concrete_t = TConcrete; using concrete_t = TConcrete;
using array_t = ArrayValue<TConcrete>; using array_t = ArrayValue<TConcrete>;
using map_t = MapValue<TConcrete>;
template<typename T>
static constexpr bool can_hold_type_v = variant_contains_v<std::remove_cv_t<T>, base_t> || std::is_arithmetic_v<T>;
private: private:
base_t base_; base_t base_ = UndefinedValue();
public: public:
ScriptValue() noexcept = default; ScriptValue() noexcept = default;
ScriptValue(const ScriptValue&) noexcept = default; ScriptValue(const ScriptValue&) noexcept = default;
@ -79,16 +95,7 @@ public:
template<typename TFunction> template<typename TFunction>
auto visit(TFunction&& function) const auto visit(TFunction&& function) const
{ {
using result_t = std::invoke_result_t<TFunction, long long>; return std::visit(function, base_);
if constexpr (std::is_same_v<result_t, void>)
{
std::visit(function, base_);
}
else
{
return std::visit(function, base_);
}
} }
[[nodiscard]] [[nodiscard]]
@ -203,7 +210,8 @@ public:
{ {
return *static_cast<copy_cv_t<std::remove_reference_t<decltype(*this)>, TConcrete>*>(this); return *static_cast<copy_cv_t<std::remove_reference_t<decltype(*this)>, TConcrete>*>(this);
} }
else if constexpr (is_any_type_v<T, TAdditional...>) else if constexpr (std::is_same_v<type_t, array_t> || std::is_same_v<type_t, map_t>
|| is_any_type_v<T, TAdditional...>)
{ {
if (std::holds_alternative<T>(base_)) if (std::holds_alternative<T>(base_))
{ {