diff --git a/include/ikarus/values/number_value.h b/include/ikarus/values/number_value.h index 2edb69b..2bdeb85 100644 --- a/include/ikarus/values/number_value.h +++ b/include/ikarus/values/number_value.h @@ -11,14 +11,14 @@ IKARUS_BEGIN_HEADER -/// \brief A true/false long doubleean-esque value. For example "Is Dead". +/// \brief A numeric value. For example "Age" or "Height". struct IkarusNumberValue; -/// \brief Creates a number value from doubles. -/// \param data The number data or null if you wish to clear the data. +/// \brief Creates a number value from long doubles. +/// \param data The number data or null if you wish to create an empty value. /// \details LibIkarus does not take ownership of this array. -/// \param data_size The size of the data array or 0 if you wish to clear the data. -/// \return The value. +/// \param data_size The size of the data array. +/// \return The value or null if an error occurs. /// \remark Must be freed with #ikarus_free. IKA_API IkarusNumberValue * ikarus_number_value_create(long double * data, size_t data_size); @@ -27,29 +27,44 @@ IKA_API IkarusNumberValue * ikarus_number_value_create(long double * data, size_ /// \remark Must be freed with #ikarus_free. IKA_API IkarusNumberValue * ikarus_number_value_create_indeterminate(); -/// \brief Fetches the underlying data of a number value. -/// \details You may adjust the returned data as per your hearts desire. -/// If you need to grow the data, use #ikarus_number_value_set with a new array. -/// Just remember that IkarusValues are plain objects, so changing them won't affect any state. -/// They will need to be submitted to other functions such as #ikarus_entity_set_value to have any effect. +/// \brief Fetches the underlying data of a number value at a specific index. /// \param value The number value. /// \pre \li Must not be null. -/// \param data_size_out An out-parameter for the size of the returned array. -/// \remark Ignored if null. -/// \return The underlying data. Owned by LibIkarus, most not be freed. -/// \warning Undefined if the value is indeterminate. -IKA_API long double * ikarus_number_value_get(IkarusNumberValue * value, size_t * data_size_out); +/// \param idx The index of the data to fetch. +/// \pre \li Must be less than the size of the value. +/// \return The underlying data or null if an error occurs or the value is indeterminate. +IKA_API long double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx); -/// \see ikarus_number_value_get -long double const * ikarus_number_value_get_const(IkarusNumberValue const * value, size_t * data_size_out); - -/// \brief Sets the data of a number value. +/// \brief Fetches the size of the underlying data of a number value. /// \param value The number value. /// \pre \li Must not be null. -/// \param new_data The new data or null if you wish to clear the data. -/// \details LibIkarus does not take ownership of this array. -/// \param new_data_size The size of the new data array or 0 if you wish to clear the data. -IKA_API void ikarus_number_value_set(IkarusNumberValue * value, long double * new_data, size_t new_data_size); +/// \return The size of the underlying data or 0 if an error occurs or the value is indeterminate. +IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value); + +/// \brief Sets the data of a number value at a specific index. +/// \param value The number value. +/// \pre \li Must not be null. +/// \param idx The index of the data to set. +/// \pre \li Must be less than the size of the value. +/// \param new_data The new data. +IKA_API void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, long double new_data); + +/// \brief Removes a data from a number value. +/// \param value The number value. +/// \pre \li Must not be null. +/// \param idx The index of the data to remove. +/// \pre \li Must be less than the size of the value. +/// \remark This will shift all data after the index by one to the left. +IKA_API void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx); + +/// \brief Inserts a data into a number value. +/// \param value The number value. +/// \pre \li Must not be null. +/// \param idx The index of the data to insert. +/// \pre \li Must be less than or equal to the size of the value. +/// \param new_data The new data. +/// \remark This will shift all data after the index by one to the right. +IKA_API void ikarus_number_insert(IkarusNumberValue * value, size_t idx, long double new_data); /// \brief Converts a number value to an entity value. /// \param value The number value to convert. diff --git a/include/ikarus/values/text_value.h b/include/ikarus/values/text_value.h index 3f1f682..08a37c8 100644 --- a/include/ikarus/values/text_value.h +++ b/include/ikarus/values/text_value.h @@ -11,14 +11,14 @@ IKARUS_BEGIN_HEADER -/// \brief A true/false char const*ean-esque value. For example "Is Dead". +/// \brief A textual value. For example "Surname" or "Description". struct IkarusTextValue; -/// \brief Creates a text value from doubles. -/// \param data The text data or null if you wish to clear the data. +/// \brief Creates a text value from strings. +/// \param data The text data or null if you wish to create an empty value. /// \details LibIkarus does not take ownership of this array. -/// \param data_size The size of the data array or 0 if you wish to clear the data. -/// \return The value. +/// \param data_size The size of the data array. +/// \return The value or null if an error occurs. /// \remark Must be freed with #ikarus_free. IKA_API IkarusTextValue * ikarus_text_value_create(char const ** data, size_t data_size); @@ -27,29 +27,39 @@ IKA_API IkarusTextValue * ikarus_text_value_create(char const ** data, size_t da /// \remark Must be freed with #ikarus_free. IKA_API IkarusTextValue * ikarus_text_value_create_indeterminate(); -/// \brief Fetches the underlying data of a text value. -/// \details You may adjust the returned data as per your hearts desire. -/// If you need to grow the data, use #ikarus_text_value_set with a new array. -/// Just remember that IkarusValues are plain objects, so changing them won't affect any state. -/// They will need to be submitted to other functions such as #ikarus_entity_set_value to have any effect. +/// \see ikarus_number_value_get +IKA_API char const * const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx); + +/// \brief Fetches the size of the underlying data of a text value. /// \param value The text value. /// \pre \li Must not be null. -/// \param data_size_out An out-parameter for the size of the returned array. -/// \remark Ignored if null. -/// \return The underlying data. Owned by LibIkarus, most not be freed. -/// \warning Undefined if the value is indeterminate. -IKA_API char ** ikarus_text_value_get(IkarusTextValue * value, size_t * data_size_out); +/// \return The size of the underlying data or 0 if an error occurs or the value is indeterminate. +IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value); -/// \see ikarus_text_value_get -char const * const * ikarus_text_value_get_const(IkarusTextValue const * value, size_t * data_size_out); - -/// \brief Sets the data of a text value. +/// \brief Sets the data of a text value at a specific index. /// \param value The text value. /// \pre \li Must not be null. -/// \param new_data The new data or null if you wish to clear the data. -/// \details LibIkarus does not take ownership of this array. -/// \param new_data_size The size of the new data array or 0 if you wish to clear the data. -IKA_API void ikarus_text_value_set(IkarusTextValue * value, char const ** new_data, size_t new_data_size); +/// \param idx The index of the data to set. +/// \pre \li Must be less than the size of the value. +/// \param new_data The new data. +IKA_API void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data); + +/// \brief Removes a data from a text value. +/// \param value The text value. +/// \pre \li Must not be null. +/// \param idx The index of the data to remove. +/// \pre \li Must be less than the size of the value. +/// \remark This will shift all data after the index by one to the left. +IKA_API void ikarus_text_value_remove(IkarusTextValue * value, size_t idx); + +/// \brief Inserts a data into a text value. +/// \param value The text value. +/// \pre \li Must not be null. +/// \param idx The index of the data to insert. +/// \pre \li Must be less than or equal to the size of the value. +/// \param new_data The new data. +/// \remark This will shift all data after the index by one to the right. +IKA_API void ikarus_text_insert(IkarusTextValue * value, size_t idx, char const * new_data); /// \brief Converts a text value to an entity value. /// \param value The text value to convert. diff --git a/include/ikarus/values/toggle_value.h b/include/ikarus/values/toggle_value.h index 89d5678..2fe45d3 100644 --- a/include/ikarus/values/toggle_value.h +++ b/include/ikarus/values/toggle_value.h @@ -14,42 +14,52 @@ IKARUS_BEGIN_HEADER /// \brief A true/false boolean-esque value. For example "Is Dead". struct IkarusToggleValue; -/// \brief Creates a toggle value from doubles. -/// \param data The toggle data or null if you wish to clear the data. -/// \details LibIkarus does not take ownership of this array. -/// \param data_size The size of the data array or 0 if you wish to clear the data. -/// \return The value. +/// \brief Creates a toggle value from booleans. +/// \return The value or null if an error occurs. /// \remark Must be freed with #ikarus_free. -IKA_API IkarusToggleValue * ikarus_toggle_value_create(bool * data, size_t data_size); +IKA_API IkarusToggleValue * ikarus_toggle_value_create(); -/// \brief Creates an indeterminate toggle value. -/// \return The value. -/// \remark Must be freed with #ikarus_free. -IKA_API IkarusToggleValue * ikarus_toggle_value_create_indeterminate(); +/// \brief Fetches the underlying data of a number value at a specific index. +/// \param value The number value. +/// \pre \li Must not be null. +/// \param idx The index of the data to fetch. +/// \pre \li Must be less than the size of the value. +/// \return The underlying data or null if an error occurs or the value is indeterminate. +IKA_API bool const * ikarus_toggle_value_get(IkarusToggleValue * value, size_t idx); -/// \brief Fetches the underlying data of a toggle value. -/// \details You may adjust the returned data as per your hearts desire. -/// If you need to grow the data, use #ikarus_toggle_value_set with a new array. -/// Just remember that IkarusValues are plain objects, so changing them won't affect any state. -/// They will need to be submitted to other functions such as #ikarus_entity_set_value to have any effect. +/// \brief Fetches the size of the underlying data of a toggle value. /// \param value The toggle value. /// \pre \li Must not be null. -/// \param data_size_out An out-parameter for the size of the returned array. -/// \remark Ignored if null. -/// \return The underlying data. Owned by LibIkarus, most not be freed. -/// \warning Undefined if the value is indeterminate. -IKA_API bool * ikarus_toggle_value_get(IkarusToggleValue * value, size_t * data_size_out); +/// \return The size of the underlying data or 0 if an error occurs or the value is indeterminate. +IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value); -/// \see ikarus_toggle_value_get -bool const * ikarus_toggle_value_get_const(IkarusToggleValue const * value, size_t * data_size_out); - -/// \brief Sets the data of a toggle value. +/// \brief Sets the data of a toggle value at a specific index. /// \param value The toggle value. /// \pre \li Must not be null. -/// \param new_data The new data or null if you wish to clear the data. -/// \details LibIkarus does not take ownership of this array. -/// \param new_data_size The size of the new data array or 0 if you wish to clear the data. -IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, bool * new_data, size_t new_data_size); +/// \param idx The index of the data to set. +/// \pre \li Must be less than the size of the value. +/// \param new_data The new data. +IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data); + +/// \brief Removes a data from a toggle value. +/// \param value The toggle value. +/// \pre \li Must not be null. +/// \param idx The index of the data to remove. +/// \pre \li Must be less than the size of the value. +IKA_API void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx); + +/// \brief Inserts a data into a toggle value. +/// \param value The toggle value. +/// \pre \li Must not be null. +/// \param idx The index of the data to insert. +/// \pre \li Must be less than or equal to the size of the value. +/// \param new_data The new data. +IKA_API void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool new_data); + +/// \brief Clears a toggle value. +/// \param value The toggle value. +/// \remark Noop if the value is indeterminate. +IKA_API void ikarus_toggle_value_clear(IkarusToggleValue * value); /// \brief Converts a toggle value to an entity value. /// \param value The toggle value to convert. diff --git a/src/values/number_value.cpp b/src/values/number_value.cpp index 4a450e3..c928b10 100644 --- a/src/values/number_value.cpp +++ b/src/values/number_value.cpp @@ -1,55 +1,35 @@ #include "ikarus/values/number_value.h" #include +#include IkarusNumberValue::IkarusNumberValue(): IkarusValue{this} {} -boost::container::vector& IkarusNumberValue::get_value() { - return _value; +IkarusNumberValue * ikarus_number_value_create() { + return new IkarusNumberValue{}; } -boost::container::vector const& IkarusNumberValue::get_value() const { - return _value; +long double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx) { + return ikarus_value_base_get(value, idx); } -IkarusNumberValue * ikarus_number_value_create(long double * data, size_t data_size) { - auto * ret = new IkarusNumberValue{}; - - ikarus_number_value_set(ret, data, data_size); - - return ret; +size_t ikarus_number_value_get_size(IkarusNumberValue const * value) { + return ikarus_value_base_get_size(value); } -IkarusNumberValue * ikarus_number_value_create_indeterminate() { - auto * ret = new IkarusNumberValue{}; - ret->set_intermediate(true); - - return ret; +void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, long double new_data) { + return ikarus_value_base_set(value, idx, new_data); } -long double * ikarus_number_value_get(IkarusNumberValue * value, size_t * data_size_out) { - // NOLINTNEXTLINE(*-pro-type-const-cast) - return const_cast(ikarus_number_value_get_const(value, data_size_out)); +void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx) { + return ikarus_value_base_remove(value, idx); } -long double const * ikarus_number_value_get_const(IkarusNumberValue const * value, size_t * data_size_out) { - if (data_size_out != nullptr) { - *data_size_out = value->get_value().size(); - } - - return value->get_value().data(); -} - -void ikarus_number_value_set(IkarusNumberValue * value, long double * new_data, size_t new_data_size) { - value->get_value().reserve(new_data_size); - - for (auto i = 0; i < new_data_size; ++i) { - // NOLINTNEXTLINE(*-pro-bounds-pointer-arithmetic) - value->get_value().emplace_back(new_data[i]); - } +void ikarus_number_value_insert(IkarusNumberValue * value, size_t idx, long double new_data) { + return ikarus_value_base_insert(value, idx, new_data); } struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value) { - return static_cast(value); + return ikarus_value_base_to_value(value); } diff --git a/src/values/number_value.hpp b/src/values/number_value.hpp index f6befe1..e1b6915 100644 --- a/src/values/number_value.hpp +++ b/src/values/number_value.hpp @@ -1,12 +1,13 @@ #pragma once -#include - #include #include struct IkarusNumberValue final : IkarusValue { +public: + using data_type = long double; + public: explicit IkarusNumberValue(); @@ -19,9 +20,5 @@ public: ~IkarusNumberValue() override = default; public: - [[nodiscard]] boost::container::vector& get_value(); - [[nodiscard]] boost::container::vector const& get_value() const; - -private: - boost::container::vector _value{}; + boost::container::vector value{}; }; diff --git a/src/values/text_value.cpp b/src/values/text_value.cpp index ba30eb8..a382c0a 100644 --- a/src/values/text_value.cpp +++ b/src/values/text_value.cpp @@ -1,55 +1,35 @@ #include "ikarus/values/text_value.h" #include +#include IkarusTextValue::IkarusTextValue(): IkarusValue{this} {} -boost::container::vector& IkarusTextValue::get_value() { - return _value; +IkarusTextValue * ikarus_text_value_create() { + return new IkarusTextValue{}; } -boost::container::vector const& IkarusTextValue::get_value() const { - return _value; +char const * ikarus_text_value_get(IkarusTextValue * value, size_t idx) { + return ikarus_value_base_get(value, idx)->data(); } -IkarusTextValue * ikarus_text_value_create(char const ** data, size_t data_size) { - auto * ret = new IkarusTextValue{}; - - ikarus_text_value_set(ret, data, data_size); - - return ret; +size_t ikarus_text_value_get_size(IkarusTextValue const * value) { + return ikarus_value_base_get_size(value); } -IkarusTextValue * ikarus_text_value_create_indeterminate() { - auto * ret = new IkarusTextValue{}; - ret->set_intermediate(true); - - return ret; +void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data) { + return ikarus_value_base_set(value, idx, new_data); } -char ** ikarus_text_value_get(IkarusTextValue * value, size_t * data_size_out) { - // NOLINTNEXTLINE(*-pro-type-const-cast) - return const_cast(ikarus_text_value_get_const(value, data_size_out)); +void ikarus_text_value_remove(IkarusTextValue * value, size_t idx) { + return ikarus_value_base_remove(value, idx); } -char const * const * ikarus_text_value_get_const(IkarusTextValue const * value, size_t * data_size_out) { - if (data_size_out != nullptr) { - *data_size_out = value->get_value().size(); - } - - return value->get_value().data(); -} - -void ikarus_text_value_set(IkarusTextValue * value, char const ** new_data, size_t new_data_size) { - value->get_value().reserve(new_data_size); - - for (auto i = 0; i < new_data_size; ++i) { - // NOLINTNEXTLINE(*-pro-bounds-pointer-arithmetic) - value->get_value().emplace_back(new_data[i]); - } +void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data) { + return ikarus_value_base_insert(value, idx, new_data); } struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value) { - return static_cast(value); + return ikarus_value_base_to_value(value); } diff --git a/src/values/text_value.hpp b/src/values/text_value.hpp index 42484a2..9596a48 100644 --- a/src/values/text_value.hpp +++ b/src/values/text_value.hpp @@ -1,13 +1,13 @@ #pragma once -#include -#include - #include #include struct IkarusTextValue final : IkarusValue { +public: + using data_type = std::string; + public: explicit IkarusTextValue(); @@ -20,9 +20,5 @@ public: ~IkarusTextValue() override = default; public: - [[nodiscard]] boost::container::vector& get_value(); - [[nodiscard]] boost::container::vector const& get_value() const; - -private: - boost::container::vector _value{}; + boost::container::vector value{}; }; diff --git a/src/values/toggle_value.cpp b/src/values/toggle_value.cpp index c03f71b..8d11e5a 100644 --- a/src/values/toggle_value.cpp +++ b/src/values/toggle_value.cpp @@ -1,60 +1,35 @@ #include "ikarus/values/toggle_value.h" #include +#include IkarusToggleValue::IkarusToggleValue(): IkarusValue{this} {} -boost::container::vector& IkarusToggleValue::get_value() { - return _value; +IkarusToggleValue * ikarus_toggle_value_create() { + return new IkarusToggleValue{}; } -boost::container::vector const& IkarusToggleValue::get_value() const { - return _value; +bool const * ikarus_toggle_value_get(IkarusToggleValue * value, size_t idx) { + return ikarus_value_base_get(value, idx); } -IkarusToggleValue * ikarus_toggle_value_create(bool * data, size_t data_size) { - auto * ret = new IkarusToggleValue{}; - - ikarus_toggle_value_set(ret, data, data_size); - - return ret; +size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value) { + return ikarus_value_base_get_size(value); } -IkarusToggleValue * ikarus_toggle_value_create_indeterminate() { - auto * ret = new IkarusToggleValue{}; - ret->set_intermediate(true); - - return ret; +void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data) { + return ikarus_value_base_set(value, idx, new_data); } -bool * ikarus_toggle_value_get(IkarusToggleValue * value, size_t * data_size_out) { - // NOLINTNEXTLINE(*-pro-type-const-cast) - return const_cast(ikarus_toggle_value_get_const(value, data_size_out)); +void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx) { + return ikarus_value_base_remove(value, idx); } -bool const * ikarus_toggle_value_get_const(IkarusToggleValue const * value, size_t * data_size_out) { - if (data_size_out != nullptr) { - *data_size_out = value->get_value().size(); - } - - return value->get_value().data(); -} - -void ikarus_toggle_value_set(IkarusToggleValue * value, bool * new_data, size_t new_data_size) { - if (new_data == nullptr || new_data_size == 0) { - value->get_value().clear(); - return; - } - - value->get_value().reserve(new_data_size); - - for (auto i = 0; i < new_data_size; ++i) { - // NOLINTNEXTLINE(*-pro-bounds-pointer-arithmetic) - value->get_value().emplace_back(new_data[i]); - } +void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool new_data) { + return ikarus_value_base_insert(value, idx, new_data); } struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value) { - return static_cast(value); + return ikarus_value_base_to_value(value); } diff --git a/src/values/toggle_value.hpp b/src/values/toggle_value.hpp index 81386a2..cb8d110 100644 --- a/src/values/toggle_value.hpp +++ b/src/values/toggle_value.hpp @@ -1,12 +1,13 @@ #pragma once -#include - #include #include struct IkarusToggleValue final : IkarusValue { +public: + using data_type = bool; + public: explicit IkarusToggleValue(); @@ -19,9 +20,5 @@ public: ~IkarusToggleValue() override = default; public: - [[nodiscard]] boost::container::vector& get_value(); - [[nodiscard]] boost::container::vector const& get_value() const; - -private: - boost::container::vector _value{}; + boost::container::vector value{}; }; diff --git a/src/values/value.cpp b/src/values/value.cpp index 7528ec8..e0e9355 100644 --- a/src/values/value.cpp +++ b/src/values/value.cpp @@ -1,9 +1,13 @@ #include "ikarus/values/value.h" +#include + #include #include +#include + #include #include #include @@ -12,11 +16,90 @@ IkarusValue::IkarusValue(Data data): _data(data) {} -bool IkarusValue::is_interminate() const { +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; + + if (auto const * obj = json.if_object(); obj == nullptr) { + return cppbase::err(FromJsonError{}); + } else { + if (auto const * type_value = obj->if_contains("type"); type_value == nullptr) { + return cppbase::err(FromJsonError{}); + } else if (type = type_value->if_int64(); type == nullptr) { + 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) { + 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); + + assign_value.operator()(ret, *data); + } + case IkarusPropertyType_Number: { + auto * ret = new IkarusToggleValue{}; + ret->set_intermediate(*intermediate); + + assign_value.operator()(ret, *data); + } + case IkarusPropertyType_Text: { + auto * ret = new IkarusToggleValue{}; + ret->set_intermediate(*intermediate); + + assign_value.operator()(ret, *data); + } + default: return cppbase::err(FromJsonError{}); + } + } +} + +boost::json::value IkarusValue::to_json() const { + 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)} + }; +} + +bool IkarusValue::is_indeterminate() const { return _indeterminate; } -void IkarusValue::set_intermediate(bool value) { +void IkarusValue::set_indeterminate(bool value) { _indeterminate = value; } @@ -29,7 +112,7 @@ IkarusValue::Data const& IkarusValue::get_data() const { } bool ikarus_value_is_indeterminate(IkarusValue const * value) { - return value->is_interminate(); + return value->is_indeterminate(); } void ikarus_value_set_indeterminate(IkarusValue * value, bool indeterminate) { @@ -39,18 +122,14 @@ void ikarus_value_set_indeterminate(IkarusValue * value, bool indeterminate) { 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_value() ? "true" : "false"; }, + [](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 ret = new char[str.size() + 1]; - - std::strncpy(ret, str.data(), str.size() + 1); - - return ret; + return strdup(str.data()); } void ikarus_value_visit( diff --git a/src/values/value.hpp b/src/values/value.hpp index ddf6601..c58d9c7 100644 --- a/src/values/value.hpp +++ b/src/values/value.hpp @@ -2,6 +2,10 @@ #include +#include + +#include + struct IkarusValue { public: using Data = std::variant; @@ -18,13 +22,12 @@ public: virtual ~IkarusValue() = default; public: - [[nodiscard]] bool is_interminate() const; - void set_intermediate(bool value); + struct FromJsonError {}; - [[nodiscard]] Data& get_data(); - [[nodiscard]] Data const& get_data() const; + [[nodiscard]] static cppbase::Result from_json(boost::json::value const& json); + [[nodiscard]] boost::json::value to_json() const; -private: - bool _indeterminate{false}; - Data _data; +public: + bool indeterminate{false}; + Data data; }; diff --git a/src/values/value_base.hpp b/src/values/value_base.hpp new file mode 100644 index 0000000..7fbb589 --- /dev/null +++ b/src/values/value_base.hpp @@ -0,0 +1,35 @@ +#pragma once + +template +typename V::data_type const * ikarus_value_base_get(V * value, size_t idx) { + if (value->is_indeterminate()) { + return nullptr; + } + + return &value->value[idx]; +} + +template +size_t ikarus_value_base_get_size(V const * value) { + return value->value.size(); +} + +template +void ikarus_value_base_set(V * value, size_t idx, typename V::data_type new_data) { + value->value[idx] = new_data; +} + +template +void ikarus_value_base_remove(V * value, size_t idx) { + value->value.erase(value->value.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); +} + +template +struct IkarusValue * ikarus_value_base_to_value(V * value) { + return static_cast(value); +} diff --git a/vendor/sqlitecpp b/vendor/sqlitecpp index 07b806f..6e39dd2 160000 --- a/vendor/sqlitecpp +++ b/vendor/sqlitecpp @@ -1 +1 @@ -Subproject commit 07b806f4d73b27a555a3ba82a97d89913e430e48 +Subproject commit 6e39dd241f8469784b8a356e7a9563fa58b0e2c4