From 7536cf4c7c80ea704402d9760a34150166849f6c Mon Sep 17 00:00:00 2001 From: Folling Date: Sun, 3 Dec 2023 11:41:06 +0100 Subject: [PATCH] implement value.hpp Signed-off-by: Folling --- src/values/number_value.hpp | 3 +- src/values/text_value.hpp | 2 +- src/values/toggle_value.hpp | 2 +- src/values/value.cpp | 152 +++++++++++++++++------------------- src/values/value.hpp | 6 +- src/values/value_base.hpp | 24 ++++-- 6 files changed, 93 insertions(+), 96 deletions(-) diff --git a/src/values/number_value.hpp b/src/values/number_value.hpp index e1b6915..359e5d2 100644 --- a/src/values/number_value.hpp +++ b/src/values/number_value.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -20,5 +21,5 @@ public: ~IkarusNumberValue() override = default; public: - boost::container::vector value{}; + boost::variant2::variant> data{}; }; diff --git a/src/values/text_value.hpp b/src/values/text_value.hpp index 9596a48..191206e 100644 --- a/src/values/text_value.hpp +++ b/src/values/text_value.hpp @@ -20,5 +20,5 @@ public: ~IkarusTextValue() override = default; public: - boost::container::vector value{}; + boost::variant2::variant> data{}; }; diff --git a/src/values/toggle_value.hpp b/src/values/toggle_value.hpp index cb8d110..750af25 100644 --- a/src/values/toggle_value.hpp +++ b/src/values/toggle_value.hpp @@ -20,5 +20,5 @@ public: ~IkarusToggleValue() override = default; public: - boost::container::vector value{}; + boost::variant2::variant> data{}; }; diff --git a/src/values/value.cpp b/src/values/value.cpp index e0e9355..dd1b60e 100644 --- a/src/values/value.cpp +++ b/src/values/value.cpp @@ -2,9 +2,10 @@ #include -#include +#include +#include -#include +#include #include @@ -14,12 +15,11 @@ #include IkarusValue::IkarusValue(Data data): - _data(data) {} + data(data) {} cppbase::Result IkarusValue::from_json(boost::json::value const& json) { - bool const * intermediate = nullptr; boost::int64_t const * type = nullptr; - boost::json::array const * data = nullptr; + boost::json::value const * data = nullptr; if (auto const * obj = json.if_object(); obj == nullptr) { return cppbase::err(FromJsonError{}); @@ -30,103 +30,91 @@ cppbase::Result IkarusValue::from_json( return cppbase::err(FromJsonError{}); } - if (auto const * intermediate_value = obj->if_contains("intermediate"); intermediate_value == nullptr) { - return cppbase::err(FromJsonError{}); - } else if (intermediate = intermediate_value->if_bool(); intermediate == nullptr) { + if (data = obj->if_contains("data"); data == nullptr) { return cppbase::err(FromJsonError{}); } - if (auto const * data = obj->if_contains("data"); data == nullptr) { - return cppbase::err(FromJsonError{}); - } else if (auto * array = data->if_array(); array == nullptr) { - return cppbase::err(FromJsonError{}); - } - - auto assign_value = - []( - auto const& value, boost::json::array const& array, auto convert = [](auto const& val) { return val; } - ) { - for (auto const& data : array) { - if (auto res = boost::json::try_value_to(data); res.has_error()) { - return cppbase::err(FromJsonError{}); - } else { - value->get_data().push_back(convert(res.value())); - return cppbase::ok(); - } - } - }; - switch (*type) { case IkarusPropertyType_Toggle: { auto * ret = new IkarusToggleValue{}; - ret->set_intermediate(*intermediate); + auto res = boost::json::try_value_to>(*data); - assign_value.operator()(ret, *data); + if (res.has_error()) { + return cppbase::err(FromJsonError{}); + } + + ret->data = std::move(res.value()); } case IkarusPropertyType_Number: { - auto * ret = new IkarusToggleValue{}; - ret->set_intermediate(*intermediate); + auto * ret = new IkarusNumberValue{}; + auto res = boost::json::try_value_to>(*data); - assign_value.operator()(ret, *data); + if (res.has_error()) { + return cppbase::err(FromJsonError{}); + } + + ret->data = std::move(res.value()); } case IkarusPropertyType_Text: { - auto * ret = new IkarusToggleValue{}; - ret->set_intermediate(*intermediate); + auto * ret = new IkarusTextValue{}; + auto res = boost::json::try_value_to>(*data); - assign_value.operator()(ret, *data); + if (res.has_error()) { + return cppbase::err(FromJsonError{}); + } + + ret->data = std::move(res.value()); + } + default: { + return cppbase::err(FromJsonError{}); } - default: return cppbase::err(FromJsonError{}); } } } boost::json::value IkarusValue::to_json() const { + auto type = boost::variant2::visit( + boost::make_overloaded_function( + []([[maybe_unused]] IkarusToggleValue const * value) { return IkarusPropertyType_Toggle; }, + []([[maybe_unused]] IkarusNumberValue const * value) { return IkarusPropertyType_Number; }, + []([[maybe_unused]] IkarusTextValue const * value) { return IkarusPropertyType_Text; } + ), + data + ); + + auto data_json = boost::variant2::visit([](auto const * value) { return boost::json::value_from(value->data); }, data); + return { - {"indeterminate", _indeterminate}, - {"type", - std::visit( - cppbase::overloaded{ - []([[maybe_unused]] IkarusToggleValue const * value) { return IkarusPropertyType_Toggle; }, - []([[maybe_unused]] IkarusNumberValue const * value) { return IkarusPropertyType_Number; }, - []([[maybe_unused]] IkarusTextValue const * value) { return IkarusPropertyType_Text; }, - }, _data - )}, - {"data", std::visit([](auto const * value) { return boost::json::value_from(value->get_data()); }, _data)} + {"type", type}, + {"data", data_json} }; } -bool IkarusValue::is_indeterminate() const { - return _indeterminate; -} - -void IkarusValue::set_indeterminate(bool value) { - _indeterminate = value; -} - -IkarusValue::Data& IkarusValue::get_data() { - return _data; -} - -IkarusValue::Data const& IkarusValue::get_data() const { - return _data; -} - bool ikarus_value_is_indeterminate(IkarusValue const * value) { - return value->is_indeterminate(); + return boost::variant2::visit( + [](auto const * value) { return boost::variant2::holds_alternative(value->data); }, + value->data + ); } void ikarus_value_set_indeterminate(IkarusValue * value, bool indeterminate) { - value->set_intermediate(indeterminate); + if (indeterminate) { + return boost::variant2::visit([](auto const * value) { value->data = boost::variant2::monostate{}; }, value->data); + } + + return boost::variant2::visit( + [](auto const * value) { value->data = boost::remove_pointer_t::data_type{}; }, value->data + ); } char const * ikarus_value_to_string(IkarusValue const * value) { - auto const str = std::visit( - cppbase::overloaded{ - [](IkarusToggleValue const * toggle_value) -> std::string { return toggle_value->get_data() ? "true" : "false"; }, - [](IkarusNumberValue const * number_value) -> std::string { return fmt::format("{}", number_value->get_value()); }, - [](IkarusTextValue const * text_value) -> std::string { return fmt::format("{}", text_value->get_value()); }, - }, - value->get_data() + auto const str = boost::variant2::visit( + boost::make_overloaded_function( + [](IkarusToggleValue const * toggle_value) -> std::string { return toggle_value->data ? "true" : "false"; }, + [](IkarusNumberValue const * number_value) -> std::string { return fmt::format("{}", number_value->data); }, + [](IkarusTextValue const * text_value) -> std::string { return fmt::format("{}", text_value->data); } + ), + value->data ); return strdup(str.data()); @@ -139,13 +127,13 @@ void ikarus_value_visit( void (*text_visitor)(IkarusTextValue *, void *), void * data ) { - std::visit( - cppbase::overloaded{ + boost::variant2::visit( + boost::make_overloaded_function( [toggle_visitor, data](IkarusToggleValue * toggle_value) { toggle_visitor(toggle_value, data); }, [number_visitor, data](IkarusNumberValue * number_value) { number_visitor(number_value, data); }, - [text_visitor, data](IkarusTextValue * text_value) { text_visitor(text_value, data); }, - }, - value->get_data() + [text_visitor, data](IkarusTextValue * text_value) { text_visitor(text_value, data); } + ), + value->data ); } @@ -156,12 +144,12 @@ void ikarus_value_visit_const( void (*text_visitor)(IkarusTextValue const *, void *), void * data ) { - std::visit( - cppbase::overloaded{ + boost::variant2::visit( + boost::make_overloaded_function( [toggle_visitor, data](IkarusToggleValue const * toggle_value) { toggle_visitor(toggle_value, data); }, [number_visitor, data](IkarusNumberValue const * number_value) { number_visitor(number_value, data); }, - [text_visitor, data](IkarusTextValue const * text_value) { text_visitor(text_value, data); }, - }, - value->get_data() + [text_visitor, data](IkarusTextValue const * text_value) { text_visitor(text_value, data); } + ), + value->data ); } diff --git a/src/values/value.hpp b/src/values/value.hpp index c58d9c7..3fbfad9 100644 --- a/src/values/value.hpp +++ b/src/values/value.hpp @@ -1,14 +1,13 @@ #pragma once -#include - #include +#include #include struct IkarusValue { public: - using Data = std::variant; + using Data = boost::variant2::variant; public: explicit IkarusValue(Data data); @@ -28,6 +27,5 @@ public: [[nodiscard]] boost::json::value to_json() const; public: - bool indeterminate{false}; Data data; }; diff --git a/src/values/value_base.hpp b/src/values/value_base.hpp index 7fbb589..bad1b91 100644 --- a/src/values/value_base.hpp +++ b/src/values/value_base.hpp @@ -2,31 +2,41 @@ template typename V::data_type const * ikarus_value_base_get(V * value, size_t idx) { - if (value->is_indeterminate()) { - return nullptr; + if (auto * data = value->data.template get_if>(); data != nullptr) { + return &(*data)[idx]; } - return &value->value[idx]; + return nullptr; } template size_t ikarus_value_base_get_size(V const * value) { - return value->value.size(); + if (auto * data = value->data.template get_if>(); data != nullptr) { + return data->size(); + } + + return 0; } template void ikarus_value_base_set(V * value, size_t idx, typename V::data_type new_data) { - value->value[idx] = new_data; + if (auto * data = value->data.template get_if>(); data != nullptr) { + (*data)[idx] = new_data; + } } template void ikarus_value_base_remove(V * value, size_t idx) { - value->value.erase(value->value.begin() + idx); + if (auto * data = value->data.template get_if>(); data != nullptr) { + data->erase(data->begin() + idx); + } } template void ikarus_value_base_insert(V * value, size_t idx, typename V::data_type new_data) { - value->value.insert(value->value.begin() + idx, new_data); + if (auto * data = value->data.template get_if>(); data != nullptr) { + data->insert(data->begin() + idx, new_data); + } } template