adjust values api to vector-esque interface

Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
Folling 2023-12-03 10:16:13 +01:00 committed by Folling
parent 3697759ceb
commit 643ece4342
No known key found for this signature in database
13 changed files with 297 additions and 220 deletions

View file

@ -11,14 +11,14 @@
IKARUS_BEGIN_HEADER 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; struct IkarusNumberValue;
/// \brief Creates a number value from doubles. /// \brief Creates a number value from long doubles.
/// \param data The number data or null if you wish to clear the data. /// \param data The number data or null if you wish to create an empty value.
/// \details LibIkarus does not take ownership of this array. /// \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. /// \param data_size The size of the data array.
/// \return The value. /// \return The value or null if an error occurs.
/// \remark Must be freed with #ikarus_free. /// \remark Must be freed with #ikarus_free.
IKA_API IkarusNumberValue * ikarus_number_value_create(long double * data, size_t data_size); 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. /// \remark Must be freed with #ikarus_free.
IKA_API IkarusNumberValue * ikarus_number_value_create_indeterminate(); IKA_API IkarusNumberValue * ikarus_number_value_create_indeterminate();
/// \brief Fetches the underlying data of a number value. /// \brief Fetches the underlying data of a number value at a specific index.
/// \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.
/// \param value The number value. /// \param value The number value.
/// \pre \li Must not be null. /// \pre \li Must not be null.
/// \param data_size_out An out-parameter for the size of the returned array. /// \param idx The index of the data to fetch.
/// \remark Ignored if null. /// \pre \li Must be less than the size of the value.
/// \return The underlying data. Owned by LibIkarus, most not be freed. /// \return The underlying data or null if an error occurs or the value is indeterminate.
/// \warning Undefined if the value is indeterminate. IKA_API long double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx);
IKA_API long double * ikarus_number_value_get(IkarusNumberValue * value, size_t * data_size_out);
/// \see ikarus_number_value_get /// \brief Fetches the size of the underlying data of a number value.
long double const * ikarus_number_value_get_const(IkarusNumberValue const * value, size_t * data_size_out);
/// \brief Sets the data of a number value.
/// \param value The number value. /// \param value The number value.
/// \pre \li Must not be null. /// \pre \li Must not be null.
/// \param new_data The new data or null if you wish to clear the data. /// \return The size of the underlying data or 0 if an error occurs or the value is indeterminate.
/// \details LibIkarus does not take ownership of this array. IKA_API size_t ikarus_number_value_get_size(IkarusNumberValue const * value);
/// \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); /// \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. /// \brief Converts a number value to an entity value.
/// \param value The number value to convert. /// \param value The number value to convert.

View file

@ -11,14 +11,14 @@
IKARUS_BEGIN_HEADER 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; struct IkarusTextValue;
/// \brief Creates a text value from doubles. /// \brief Creates a text value from strings.
/// \param data The text data or null if you wish to clear the data. /// \param data The text data or null if you wish to create an empty value.
/// \details LibIkarus does not take ownership of this array. /// \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. /// \param data_size The size of the data array.
/// \return The value. /// \return The value or null if an error occurs.
/// \remark Must be freed with #ikarus_free. /// \remark Must be freed with #ikarus_free.
IKA_API IkarusTextValue * ikarus_text_value_create(char const ** data, size_t data_size); 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. /// \remark Must be freed with #ikarus_free.
IKA_API IkarusTextValue * ikarus_text_value_create_indeterminate(); IKA_API IkarusTextValue * ikarus_text_value_create_indeterminate();
/// \brief Fetches the underlying data of a text value. /// \see ikarus_number_value_get
/// \details You may adjust the returned data as per your hearts desire. IKA_API char const * const * ikarus_text_value_get(IkarusTextValue const * value, size_t idx);
/// 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. /// \brief Fetches the size of the underlying data of a text value.
/// They will need to be submitted to other functions such as #ikarus_entity_set_value to have any effect.
/// \param value The text value. /// \param value The text value.
/// \pre \li Must not be null. /// \pre \li Must not be null.
/// \param data_size_out An out-parameter for the size of the returned array. /// \return The size of the underlying data or 0 if an error occurs or the value is indeterminate.
/// \remark Ignored if null. IKA_API size_t ikarus_text_value_get_size(IkarusTextValue const * value);
/// \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);
/// \see ikarus_text_value_get /// \brief Sets the data of a text value at a specific index.
char const * const * ikarus_text_value_get_const(IkarusTextValue const * value, size_t * data_size_out);
/// \brief Sets the data of a text value.
/// \param value The text value. /// \param value The text value.
/// \pre \li Must not be null. /// \pre \li Must not be null.
/// \param new_data The new data or null if you wish to clear the data. /// \param idx The index of the data to set.
/// \details LibIkarus does not take ownership of this array. /// \pre \li Must be less than the size of the value.
/// \param new_data_size The size of the new data array or 0 if you wish to clear the data. /// \param new_data The new data.
IKA_API void ikarus_text_value_set(IkarusTextValue * value, char const ** new_data, size_t new_data_size); 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. /// \brief Converts a text value to an entity value.
/// \param value The text value to convert. /// \param value The text value to convert.

View file

@ -14,42 +14,52 @@ IKARUS_BEGIN_HEADER
/// \brief A true/false boolean-esque value. For example "Is Dead". /// \brief A true/false boolean-esque value. For example "Is Dead".
struct IkarusToggleValue; struct IkarusToggleValue;
/// \brief Creates a toggle value from doubles. /// \brief Creates a toggle value from booleans.
/// \param data The toggle data or null if you wish to clear the data. /// \return The value or null if an error occurs.
/// \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.
/// \remark Must be freed with #ikarus_free. /// \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. /// \brief Fetches the underlying data of a number value at a specific index.
/// \return The value. /// \param value The number value.
/// \remark Must be freed with #ikarus_free. /// \pre \li Must not be null.
IKA_API IkarusToggleValue * ikarus_toggle_value_create_indeterminate(); /// \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. /// \brief Fetches the size of 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.
/// \param value The toggle value. /// \param value The toggle value.
/// \pre \li Must not be null. /// \pre \li Must not be null.
/// \param data_size_out An out-parameter for the size of the returned array. /// \return The size of the underlying data or 0 if an error occurs or the value is indeterminate.
/// \remark Ignored if null. IKA_API size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value);
/// \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);
/// \see ikarus_toggle_value_get /// \brief Sets the data of a toggle value at a specific index.
bool const * ikarus_toggle_value_get_const(IkarusToggleValue const * value, size_t * data_size_out);
/// \brief Sets the data of a toggle value.
/// \param value The toggle value. /// \param value The toggle value.
/// \pre \li Must not be null. /// \pre \li Must not be null.
/// \param new_data The new data or null if you wish to clear the data. /// \param idx The index of the data to set.
/// \details LibIkarus does not take ownership of this array. /// \pre \li Must be less than the size of the value.
/// \param new_data_size The size of the new data array or 0 if you wish to clear the data. /// \param new_data The new data.
IKA_API void ikarus_toggle_value_set(IkarusToggleValue * value, bool * new_data, size_t new_data_size); 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. /// \brief Converts a toggle value to an entity value.
/// \param value The toggle value to convert. /// \param value The toggle value to convert.

View file

@ -1,55 +1,35 @@
#include "ikarus/values/number_value.h" #include "ikarus/values/number_value.h"
#include <values/number_value.hpp> #include <values/number_value.hpp>
#include <values/value_base.hpp>
IkarusNumberValue::IkarusNumberValue(): IkarusNumberValue::IkarusNumberValue():
IkarusValue{this} {} IkarusValue{this} {}
boost::container::vector<long double>& IkarusNumberValue::get_value() { IkarusNumberValue * ikarus_number_value_create() {
return _value; return new IkarusNumberValue{};
} }
boost::container::vector<long double> const& IkarusNumberValue::get_value() const { long double const * ikarus_number_value_get(IkarusNumberValue * value, size_t idx) {
return _value; return ikarus_value_base_get(value, idx);
} }
IkarusNumberValue * ikarus_number_value_create(long double * data, size_t data_size) { size_t ikarus_number_value_get_size(IkarusNumberValue const * value) {
auto * ret = new IkarusNumberValue{}; return ikarus_value_base_get_size(value);
ikarus_number_value_set(ret, data, data_size);
return ret;
} }
IkarusNumberValue * ikarus_number_value_create_indeterminate() { void ikarus_number_value_set(IkarusNumberValue * value, size_t idx, long double new_data) {
auto * ret = new IkarusNumberValue{}; return ikarus_value_base_set(value, idx, new_data);
ret->set_intermediate(true);
return ret;
} }
long double * ikarus_number_value_get(IkarusNumberValue * value, size_t * data_size_out) { void ikarus_number_value_remove(IkarusNumberValue * value, size_t idx) {
// NOLINTNEXTLINE(*-pro-type-const-cast) return ikarus_value_base_remove(value, idx);
return const_cast<long double *>(ikarus_number_value_get_const(value, data_size_out));
} }
long double const * ikarus_number_value_get_const(IkarusNumberValue const * value, size_t * data_size_out) { void ikarus_number_value_insert(IkarusNumberValue * value, size_t idx, long double new_data) {
if (data_size_out != nullptr) { return ikarus_value_base_insert(value, idx, new_data);
*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]);
}
} }
struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value) { struct IkarusValue * ikarus_number_value_to_value(IkarusNumberValue * value) {
return static_cast<IkarusValue *>(value); return ikarus_value_base_to_value(value);
} }

View file

@ -1,12 +1,13 @@
#pragma once #pragma once
#include <vector>
#include <boost/container/vector.hpp> #include <boost/container/vector.hpp>
#include <values/value.hpp> #include <values/value.hpp>
struct IkarusNumberValue final : IkarusValue { struct IkarusNumberValue final : IkarusValue {
public:
using data_type = long double;
public: public:
explicit IkarusNumberValue(); explicit IkarusNumberValue();
@ -19,9 +20,5 @@ public:
~IkarusNumberValue() override = default; ~IkarusNumberValue() override = default;
public: public:
[[nodiscard]] boost::container::vector<long double>& get_value(); boost::container::vector<data_type> value{};
[[nodiscard]] boost::container::vector<long double> const& get_value() const;
private:
boost::container::vector<long double> _value{};
}; };

View file

@ -1,55 +1,35 @@
#include "ikarus/values/text_value.h" #include "ikarus/values/text_value.h"
#include <values/text_value.hpp> #include <values/text_value.hpp>
#include <values/value_base.hpp>
IkarusTextValue::IkarusTextValue(): IkarusTextValue::IkarusTextValue():
IkarusValue{this} {} IkarusValue{this} {}
boost::container::vector<char const *>& IkarusTextValue::get_value() { IkarusTextValue * ikarus_text_value_create() {
return _value; return new IkarusTextValue{};
} }
boost::container::vector<char const *> const& IkarusTextValue::get_value() const { char const * ikarus_text_value_get(IkarusTextValue * value, size_t idx) {
return _value; return ikarus_value_base_get(value, idx)->data();
} }
IkarusTextValue * ikarus_text_value_create(char const ** data, size_t data_size) { size_t ikarus_text_value_get_size(IkarusTextValue const * value) {
auto * ret = new IkarusTextValue{}; return ikarus_value_base_get_size(value);
ikarus_text_value_set(ret, data, data_size);
return ret;
} }
IkarusTextValue * ikarus_text_value_create_indeterminate() { void ikarus_text_value_set(IkarusTextValue * value, size_t idx, char const * new_data) {
auto * ret = new IkarusTextValue{}; return ikarus_value_base_set(value, idx, new_data);
ret->set_intermediate(true);
return ret;
} }
char ** ikarus_text_value_get(IkarusTextValue * value, size_t * data_size_out) { void ikarus_text_value_remove(IkarusTextValue * value, size_t idx) {
// NOLINTNEXTLINE(*-pro-type-const-cast) return ikarus_value_base_remove(value, idx);
return const_cast<char **>(ikarus_text_value_get_const(value, data_size_out));
} }
char const * const * ikarus_text_value_get_const(IkarusTextValue const * value, size_t * data_size_out) { void ikarus_text_value_insert(IkarusTextValue * value, size_t idx, char const * new_data) {
if (data_size_out != nullptr) { return ikarus_value_base_insert(value, idx, new_data);
*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]);
}
} }
struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value) { struct IkarusValue * ikarus_text_value_to_value(IkarusTextValue * value) {
return static_cast<IkarusValue *>(value); return ikarus_value_base_to_value(value);
} }

View file

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <string>
#include <vector>
#include <boost/container/vector.hpp> #include <boost/container/vector.hpp>
#include <values/value.hpp> #include <values/value.hpp>
struct IkarusTextValue final : IkarusValue { struct IkarusTextValue final : IkarusValue {
public:
using data_type = std::string;
public: public:
explicit IkarusTextValue(); explicit IkarusTextValue();
@ -20,9 +20,5 @@ public:
~IkarusTextValue() override = default; ~IkarusTextValue() override = default;
public: public:
[[nodiscard]] boost::container::vector<char const *>& get_value(); boost::container::vector<data_type> value{};
[[nodiscard]] boost::container::vector<char const *> const& get_value() const;
private:
boost::container::vector<char const *> _value{};
}; };

View file

@ -1,60 +1,35 @@
#include "ikarus/values/toggle_value.h" #include "ikarus/values/toggle_value.h"
#include <values/toggle_value.hpp> #include <values/toggle_value.hpp>
#include <values/value_base.hpp>
IkarusToggleValue::IkarusToggleValue(): IkarusToggleValue::IkarusToggleValue():
IkarusValue{this} {} IkarusValue{this} {}
boost::container::vector<bool>& IkarusToggleValue::get_value() { IkarusToggleValue * ikarus_toggle_value_create() {
return _value; return new IkarusToggleValue{};
} }
boost::container::vector<bool> const& IkarusToggleValue::get_value() const { bool const * ikarus_toggle_value_get(IkarusToggleValue * value, size_t idx) {
return _value; return ikarus_value_base_get(value, idx);
} }
IkarusToggleValue * ikarus_toggle_value_create(bool * data, size_t data_size) { size_t ikarus_toggle_value_get_size(IkarusToggleValue const * value) {
auto * ret = new IkarusToggleValue{}; return ikarus_value_base_get_size(value);
ikarus_toggle_value_set(ret, data, data_size);
return ret;
} }
IkarusToggleValue * ikarus_toggle_value_create_indeterminate() { void ikarus_toggle_value_set(IkarusToggleValue * value, size_t idx, bool new_data) {
auto * ret = new IkarusToggleValue{}; return ikarus_value_base_set(value, idx, new_data);
ret->set_intermediate(true);
return ret;
} }
bool * ikarus_toggle_value_get(IkarusToggleValue * value, size_t * data_size_out) { void ikarus_toggle_value_remove(IkarusToggleValue * value, size_t idx) {
// NOLINTNEXTLINE(*-pro-type-const-cast) return ikarus_value_base_remove(value, idx);
return const_cast<bool *>(ikarus_toggle_value_get_const(value, data_size_out));
} }
bool const * ikarus_toggle_value_get_const(IkarusToggleValue const * value, size_t * data_size_out) { void ikarus_toggle_value_insert(IkarusToggleValue * value, size_t idx, bool new_data) {
if (data_size_out != nullptr) { return ikarus_value_base_insert(value, idx, new_data);
*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]);
}
} }
struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value) { struct IkarusValue * ikarus_toggle_value_to_value(IkarusToggleValue * value) {
return static_cast<IkarusValue *>(value); return ikarus_value_base_to_value(value);
} }

View file

@ -1,12 +1,13 @@
#pragma once #pragma once
#include <vector>
#include <boost/container/vector.hpp> #include <boost/container/vector.hpp>
#include <values/value.hpp> #include <values/value.hpp>
struct IkarusToggleValue final : IkarusValue { struct IkarusToggleValue final : IkarusValue {
public:
using data_type = bool;
public: public:
explicit IkarusToggleValue(); explicit IkarusToggleValue();
@ -19,9 +20,5 @@ public:
~IkarusToggleValue() override = default; ~IkarusToggleValue() override = default;
public: public:
[[nodiscard]] boost::container::vector<bool>& get_value(); boost::container::vector<data_type> value{};
[[nodiscard]] boost::container::vector<bool> const& get_value() const;
private:
boost::container::vector<bool> _value{};
}; };

View file

@ -1,9 +1,13 @@
#include "ikarus/values/value.h" #include "ikarus/values/value.h"
#include <string>
#include <fmt/format.h> #include <fmt/format.h>
#include <cppbase/templates.hpp> #include <cppbase/templates.hpp>
#include <ikarus/objects/properties/property_type.h>
#include <values/number_value.hpp> #include <values/number_value.hpp>
#include <values/text_value.hpp> #include <values/text_value.hpp>
#include <values/toggle_value.hpp> #include <values/toggle_value.hpp>
@ -12,11 +16,90 @@
IkarusValue::IkarusValue(Data data): IkarusValue::IkarusValue(Data data):
_data(data) {} _data(data) {}
bool IkarusValue::is_interminate() const { cppbase::Result<IkarusValue, IkarusValue::FromJsonError> 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 =
[]<typename T>(
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<T>(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()<bool, bool>(ret, *data);
}
case IkarusPropertyType_Number: {
auto * ret = new IkarusToggleValue{};
ret->set_intermediate(*intermediate);
assign_value.operator()<long double>(ret, *data);
}
case IkarusPropertyType_Text: {
auto * ret = new IkarusToggleValue{};
ret->set_intermediate(*intermediate);
assign_value.operator()<std::string>(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; return _indeterminate;
} }
void IkarusValue::set_intermediate(bool value) { void IkarusValue::set_indeterminate(bool value) {
_indeterminate = value; _indeterminate = value;
} }
@ -29,7 +112,7 @@ IkarusValue::Data const& IkarusValue::get_data() const {
} }
bool ikarus_value_is_indeterminate(IkarusValue const * value) { 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) { 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) { char const * ikarus_value_to_string(IkarusValue const * value) {
auto const str = std::visit( auto const str = std::visit(
cppbase::overloaded{ 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()); }, [](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()); }, [](IkarusTextValue const * text_value) -> std::string { return fmt::format("{}", text_value->get_value()); },
}, },
value->get_data() value->get_data()
); );
auto * const ret = new char[str.size() + 1]; return strdup(str.data());
std::strncpy(ret, str.data(), str.size() + 1);
return ret;
} }
void ikarus_value_visit( void ikarus_value_visit(

View file

@ -2,6 +2,10 @@
#include <variant> #include <variant>
#include <boost/json.hpp>
#include <cppbase/result.hpp>
struct IkarusValue { struct IkarusValue {
public: public:
using Data = std::variant<struct IkarusToggleValue *, struct IkarusNumberValue *, struct IkarusTextValue *>; using Data = std::variant<struct IkarusToggleValue *, struct IkarusNumberValue *, struct IkarusTextValue *>;
@ -18,13 +22,12 @@ public:
virtual ~IkarusValue() = default; virtual ~IkarusValue() = default;
public: public:
[[nodiscard]] bool is_interminate() const; struct FromJsonError {};
void set_intermediate(bool value);
[[nodiscard]] Data& get_data(); [[nodiscard]] static cppbase::Result<IkarusValue, FromJsonError> from_json(boost::json::value const& json);
[[nodiscard]] Data const& get_data() const; [[nodiscard]] boost::json::value to_json() const;
private: public:
bool _indeterminate{false}; bool indeterminate{false};
Data _data; Data data;
}; };

35
src/values/value_base.hpp Normal file
View file

@ -0,0 +1,35 @@
#pragma once
template<typename V>
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<typename V>
size_t ikarus_value_base_get_size(V const * value) {
return value->value.size();
}
template<typename V>
void ikarus_value_base_set(V * value, size_t idx, typename V::data_type new_data) {
value->value[idx] = new_data;
}
template<typename V>
void ikarus_value_base_remove(V * value, size_t idx) {
value->value.erase(value->value.begin() + idx);
}
template<typename V>
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<typename V>
struct IkarusValue * ikarus_value_base_to_value(V * value) {
return static_cast<IkarusValue *>(value);
}

2
vendor/sqlitecpp vendored

@ -1 +1 @@
Subproject commit 07b806f4d73b27a555a3ba82a97d89913e430e48 Subproject commit 6e39dd241f8469784b8a356e7a9563fa58b0e2c4