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 <string>
#include <unordered_map>
#include <variant>
#include <vector>
@ -14,6 +15,16 @@
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
//
@ -26,12 +37,12 @@ template<typename TScriptValue>
struct ArrayValue
{
std::vector<TScriptValue> values;
};
bool operator==(const ArrayValue& other) const;
inline bool operator!=(const ArrayValue& other) const {
return !(*this == other);
}
std::partial_ordering operator<=>(const ArrayValue& other) const;
template<typename TScriptValue>
struct MapValue
{
std::unordered_map<std::string, TScriptValue> values;
};
struct UndefinedValue
@ -52,6 +63,7 @@ using script_value_base_t = std::variant<
script_float_t,
std::string,
ArrayValue<TConcrete>,
MapValue<TConcrete>,
TAdditional...
>;
@ -62,8 +74,12 @@ public:
using base_t = script_value_base_t<TConcrete, TAdditional...>;
using concrete_t = 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:
base_t base_;
base_t base_ = UndefinedValue();
public:
ScriptValue() noexcept = default;
ScriptValue(const ScriptValue&) noexcept = default;
@ -79,16 +95,7 @@ public:
template<typename TFunction>
auto visit(TFunction&& function) const
{
using result_t = std::invoke_result_t<TFunction, long long>;
if constexpr (std::is_same_v<result_t, void>)
{
std::visit(function, base_);
}
else
{
return std::visit(function, base_);
}
return std::visit(function, base_);
}
[[nodiscard]]
@ -203,7 +210,8 @@ public:
{
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_))
{