From cc73cf000ddd251726cc99f9961c077c8d1aa64f Mon Sep 17 00:00:00 2001 From: Folling Date: Mon, 27 Nov 2023 13:13:54 +0100 Subject: [PATCH] fixup compile errors and allow fetching property properly from cache Signed-off-by: Folling --- include/ikarus/objects/object_type.h | 8 +- .../objects/properties/number_property.h | 1 - .../ikarus/objects/properties/text_property.h | 1 - .../objects/properties/toggle_property.h | 1 - src/objects/blueprint.cpp | 99 +++++++------------ src/objects/blueprint.hpp | 2 +- src/objects/object.cpp | 4 + src/objects/object.hpp | 6 +- src/objects/properties/number_property.cpp | 4 + src/objects/properties/number_property.hpp | 11 ++- src/objects/properties/property.cpp | 57 +++++++++++ src/objects/properties/property.hpp | 23 ++++- src/objects/properties/text_property.cpp | 4 + src/objects/properties/text_property.hpp | 12 +-- src/objects/properties/toggle_property.cpp | 6 ++ src/objects/properties/toggle_property.hpp | 1 + src/persistence/function_context.cpp | 2 +- src/persistence/project.cpp | 26 ++++- src/persistence/project.hpp | 17 ++-- src/values/value.cpp | 25 ++++- src/values/value.hpp | 25 ++--- 21 files changed, 213 insertions(+), 122 deletions(-) diff --git a/include/ikarus/objects/object_type.h b/include/ikarus/objects/object_type.h index 578919a..efb6609 100644 --- a/include/ikarus/objects/object_type.h +++ b/include/ikarus/objects/object_type.h @@ -15,11 +15,11 @@ enum IkarusObjectType { /// \brief Not an object or no object. IkarusObjectType_None = 0, /// \brief An IkarusEntity. - IkarusObjectType_Entity = 0b00000011, - /// \brief An IkarusProperty. - IkarusObjectType_Property = 0b00000010, + IkarusObjectType_Entity = 0b00000001, /// \brief An IkarusBlueprint. - IkarusObjectType_Blueprint = 0b00000001, + IkarusObjectType_Blueprint = 0b00000010, + /// \brief An IkarusProperty. + IkarusObjectType_Property = 0b00000011, }; IKARUS_END_HEADER diff --git a/include/ikarus/objects/properties/number_property.h b/include/ikarus/objects/properties/number_property.h index 7787cc6..9b4fa4d 100644 --- a/include/ikarus/objects/properties/number_property.h +++ b/include/ikarus/objects/properties/number_property.h @@ -21,7 +21,6 @@ IKA_API IkarusNumberProperty * ikarus_number_property_create( /// \param property The number property. /// \pre \li Must not be null. /// \pre \li Must exist. -/// \remark The settings take ownership of the value, the caller must not free it. IKA_API struct IkarusNumberValue * ikarus_number_property_get_default_value(struct IkarusNumberProperty * property); /// \brief Sets the default value for a number property. diff --git a/include/ikarus/objects/properties/text_property.h b/include/ikarus/objects/properties/text_property.h index ad90bf6..0e6a435 100644 --- a/include/ikarus/objects/properties/text_property.h +++ b/include/ikarus/objects/properties/text_property.h @@ -21,7 +21,6 @@ IKA_API IkarusTextProperty * ikarus_text_property_create( /// \param property The text property. /// \pre \li Must not be null. /// \pre \li Must exist. -/// \remark The settings take ownership of the value, the caller must not free it. IKA_API struct IkarusTextValue * ikarus_text_property_get_default_value(struct IkarusTextProperty * property); /// \brief Sets the default value for a text property. diff --git a/include/ikarus/objects/properties/toggle_property.h b/include/ikarus/objects/properties/toggle_property.h index 9e8119d..0d67304 100644 --- a/include/ikarus/objects/properties/toggle_property.h +++ b/include/ikarus/objects/properties/toggle_property.h @@ -21,7 +21,6 @@ IKA_API IkarusToggleProperty * ikarus_toggle_property_create( /// \param property The toggle property. /// \pre \li Must not be null. /// \pre \li Must exist. -/// \remark The settings take ownership of the value, the caller must not free it. IKA_API struct IkarusToggleValue * ikarus_toggle_property_get_default_value(struct IkarusToggleProperty * property); /// \brief Sets the default value for a toggle property. diff --git a/src/objects/blueprint.cpp b/src/objects/blueprint.cpp index 3971d9e..bdbea93 100644 --- a/src/objects/blueprint.cpp +++ b/src/objects/blueprint.cpp @@ -17,25 +17,15 @@ IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id): IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name) { LOG_INFO("creating new blueprint"); - if (project == nullptr) { - LOG_ERROR("project is nullptr"); - return nullptr; - } + LOG_DEBUG("project={}; name={}", project->get_path().c_str(), name); auto * ctx = project->get_function_context(); - if (name == nullptr) { - ctx->set_error("name is nullptr", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); - return nullptr; - } - if (cppbase::is_empty_or_blank(name)) { ctx->set_error("name is empty or blank", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); return nullptr; } - LOG_DEBUG("project={}; name={}", project->get_path().c_str(), name); - VTRYRV( auto const id, nullptr, @@ -77,15 +67,10 @@ IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char c void ikarus_blueprint_delete(IkarusBlueprint * blueprint) { LOG_INFO("deleting blueprint"); - if (blueprint == nullptr) { - LOG_ERROR("blueprint is nullptr"); - return; - } + LOG_DEBUG("project={};blueprint={}", blueprint->get_project()->get_path().c_str(), blueprint->get_id()); auto * ctx = blueprint->get_project()->get_function_context(); - LOG_DEBUG("blueprint={}", blueprint->get_id()); - TRYRV( , blueprint->get_project() @@ -101,7 +86,7 @@ void ikarus_blueprint_delete(IkarusBlueprint * blueprint) { }) ); - LOG_VERBOSE("blueprint was successfully deleted from database, freeing blueprint"); + LOG_VERBOSE("blueprint was successfully deleted from database, freeing"); blueprint->get_project()->uncache_blueprint(blueprint); @@ -111,11 +96,6 @@ void ikarus_blueprint_delete(IkarusBlueprint * blueprint) { size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint) { LOG_VERBOSE("fetching blueprint property count"); - if (blueprint == nullptr) { - LOG_ERROR("blueprint is nullptr"); - return 0; - } - auto * ctx = blueprint->get_project()->get_function_context(); LOG_DEBUG("blueprint={}", blueprint->get_id()); @@ -148,20 +128,15 @@ void ikarus_blueprint_get_properties( ) { LOG_VERBOSE("fetching blueprint properties"); - if (blueprint == nullptr) { - LOG_ERROR("blueprint is nullptr"); - return; - } + LOG_DEBUG( + "project={};blueprint={};properties_out_size={}", + blueprint->get_project()->get_path().c_str(), + blueprint->get_id(), + properties_out_size + ); auto * ctx = blueprint->get_project()->get_function_context(); - if (properties_out == nullptr) { - ctx->set_error("properties_out is null", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); - return; - } - - LOG_DEBUG("blueprint={}; properties_out_size={}", blueprint->get_id(), properties_out_size); - IkarusId ids[properties_out_size]; TRYRV( @@ -187,8 +162,23 @@ void ikarus_blueprint_get_properties( LOG_DEBUG("blueprint properties: [{}]", fmt::join(ids, ids + properties_out_size, ", ")); for (size_t i = 0; i < properties_out_size; ++i) { + auto const id = ids[i]; + + VTRYRV( + auto const type, + , + IkarusProperty::get_property_type(blueprint->get_project(), id).on_error([ctx, id](auto const& err) { + ctx->set_error( + fmt::format("failed to fetch property {}'s type: {}", id, err), + true, + IkarusErrorInfo_Source_SubSystem, + IkarusErrorInfo_Type_SubSystem_Database + ); + }) + ); + /// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - properties_out[i] = blueprint->get_project()->get_property(ids[i]); + properties_out[i] = blueprint->get_project()->get_property(id, type); } LOG_VERBOSE("successfully fetched blueprint properties"); @@ -197,15 +187,10 @@ void ikarus_blueprint_get_properties( size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprint) { LOG_VERBOSE("fetching blueprint linked entity count"); - if (blueprint == nullptr) { - LOG_ERROR("blueprint is nullptr"); - return 0; - } + LOG_DEBUG("project={};blueprint={}", blueprint->get_project()->get_path().c_str(), blueprint->get_id()); auto * ctx = blueprint->get_project()->get_function_context(); - LOG_DEBUG("blueprint={}", blueprint->get_id()); - VTRYRV( auto count, 0, @@ -234,20 +219,15 @@ void ikarus_blueprint_get_linked_entities( ) { LOG_VERBOSE("fetching blueprint linked entities"); - if (blueprint == nullptr) { - LOG_ERROR("blueprint is nullptr"); - return; - } + LOG_DEBUG( + "project={};blueprint={};entities_out_size={}", + blueprint->get_project()->get_path().c_str(), + blueprint->get_id(), + entities_out_size + ); auto * ctx = blueprint->get_project()->get_function_context(); - if (entities_out == nullptr) { - ctx->set_error("entities_out is null", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input); - return; - } - - LOG_DEBUG("blueprint={}; entities_out_size={}", blueprint->get_id(), entities_out_size); - IkarusId ids[entities_out_size]; TRYRV( @@ -281,22 +261,9 @@ void ikarus_blueprint_get_linked_entities( } IkarusObject * ikarus_blueprint_to_object(IkarusBlueprint * blueprint) { - return const_cast(ikarus_blueprint_to_object_const(blueprint)); + return static_cast(blueprint); } IkarusObject const * ikarus_blueprint_to_object_const(IkarusBlueprint const * blueprint) { - LOG_VERBOSE("casting blueprint to object"); - - if (blueprint == nullptr) { - LOG_ERROR("blueprint is nullptr"); - return nullptr; - } - - // auto * ctx = blueprint->project->function_context(); - - LOG_DEBUG("blueprint={}", blueprint->get_id()); - - LOG_VERBOSE("successfully casted blueprint to object"); - return static_cast(blueprint); } diff --git a/src/objects/blueprint.hpp b/src/objects/blueprint.hpp index 445efdb..41042ba 100644 --- a/src/objects/blueprint.hpp +++ b/src/objects/blueprint.hpp @@ -3,7 +3,7 @@ #include struct IkarusBlueprint final : IkarusObject { - inline IkarusBlueprint(struct IkarusProject * project, IkarusId id); + IkarusBlueprint(struct IkarusProject * project, IkarusId id); IkarusBlueprint(IkarusBlueprint const&) = default; IkarusBlueprint(IkarusBlueprint&&) = default; diff --git a/src/objects/object.cpp b/src/objects/object.cpp index 72aba6e..2ce961e 100644 --- a/src/objects/object.cpp +++ b/src/objects/object.cpp @@ -1,5 +1,9 @@ #include "object.hpp" +IkarusObject::IkarusObject(IkarusProject * project, IkarusId id): + _project{project}, + _id{id} {} + IkarusProject * IkarusObject::get_project() { return _project; } diff --git a/src/objects/object.hpp b/src/objects/object.hpp index ee1b147..bb28da5 100644 --- a/src/objects/object.hpp +++ b/src/objects/object.hpp @@ -15,11 +15,11 @@ public: virtual ~IkarusObject() = default; public: - [[nodiscard]] inline struct IkarusProject * get_project(); + [[nodiscard]] struct IkarusProject * get_project(); - [[nodiscard]] inline struct IkarusProject * get_project() const; + [[nodiscard]] struct IkarusProject * get_project() const; - [[nodiscard]] inline IkarusId get_id() const; + [[nodiscard]] IkarusId get_id() const; private: struct IkarusProject mutable * _project; diff --git a/src/objects/properties/number_property.cpp b/src/objects/properties/number_property.cpp index e69de29..d06cfb5 100644 --- a/src/objects/properties/number_property.cpp +++ b/src/objects/properties/number_property.cpp @@ -0,0 +1,4 @@ +#include "number_property.hpp" + +IkarusNumberProperty::IkarusNumberProperty(IkarusProject * project, IkarusId id): + IkarusProperty{project, id, this} {} diff --git a/src/objects/properties/number_property.hpp b/src/objects/properties/number_property.hpp index dd5f8a2..df2ab7e 100644 --- a/src/objects/properties/number_property.hpp +++ b/src/objects/properties/number_property.hpp @@ -1,5 +1,8 @@ -// -// Created by Jonathan Purol on 26.11.23. -// +#pragma once -export module number_property.hpp; +#include + +struct IkarusNumberProperty final : IkarusProperty { +public: + IkarusNumberProperty(struct IkarusProject * project, IkarusId id); +}; diff --git a/src/objects/properties/property.cpp b/src/objects/properties/property.cpp index e69de29..3afcf66 100644 --- a/src/objects/properties/property.cpp +++ b/src/objects/properties/property.cpp @@ -0,0 +1,57 @@ +#include "property.hpp" + +#include + +#include + +#include +#include + +IkarusProperty::IkarusProperty(IkarusProject * project, IkarusId id, Data data): + IkarusObject{project, id}, + _data{data} {} + +cppbase::Result IkarusProperty::get_property_type( + IkarusProject * project, IkarusId id +) { + LOG_DEBUG("fetching unboxed property type"); + + LOG_VERBOSE("project={};property={}", project->get_path().c_str(), id); + + VTRY(auto const type, project->get_db()->query_one("SELECT `type` FROM `objects` WHERE `id` = ?", id)); + + return cppbase::ok(static_cast(type)); +} + +IKA_API void ikarus_property_delete(IkarusProperty * property) { + LOG_INFO("deleting property"); + + LOG_VERBOSE("project={};property={}", property->get_project()->get_path().c_str(), property->get_id()); + + auto * ctx = property->get_project()->get_function_context(); + + TRYRV( + , + property->get_project() + ->get_db() + ->execute("DELETE FROM `objects` WHERE `id` = ?", property->get_id()) + .on_error([ctx](auto const& err) { + ctx->set_error( + fmt::format("failed to delete property from objects table: {}", err), + true, + IkarusErrorInfo_Source_SubSystem, + IkarusErrorInfo_Type_SubSystem_Database + ); + }) + ); + + LOG_VERBOSE("property was successfully deleted from database, freeing"); + + property->get_project()->uncache_property(property); + + LOG_VERBOSE("successfully deleted property"); +} + +IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property) { + LOG_DEBUG("fetching property type"); +} diff --git a/src/objects/properties/property.hpp b/src/objects/properties/property.hpp index 1a74577..b11a8ff 100644 --- a/src/objects/properties/property.hpp +++ b/src/objects/properties/property.hpp @@ -1,9 +1,27 @@ #pragma once +#include + +#include + +#include + +#include + #include struct IkarusProperty : IkarusObject { - IkarusProperty(struct IkarusProject * project, IkarusId id); +public: + using Data = std::variant; + +public: + /// \brief Helper to fetch a type for a property that isn't yet wrapped in an object + [[nodiscard]] static cppbase::Result get_property_type( + struct IkarusProject * project, IkarusId id + ); + +public: + IkarusProperty(struct IkarusProject * project, IkarusId id, Data data); IkarusProperty(IkarusProperty const&) = default; IkarusProperty(IkarusProperty&&) = default; @@ -12,4 +30,7 @@ struct IkarusProperty : IkarusObject { IkarusProperty& operator=(IkarusProperty&&) = default; ~IkarusProperty() override = default; + +private: + Data _data; }; diff --git a/src/objects/properties/text_property.cpp b/src/objects/properties/text_property.cpp index e69de29..fd64154 100644 --- a/src/objects/properties/text_property.cpp +++ b/src/objects/properties/text_property.cpp @@ -0,0 +1,4 @@ +#include "text_property.hpp" + +IkarusTextProperty::IkarusTextProperty(IkarusProject * project, IkarusId id): + IkarusProperty{project, id, this} {} diff --git a/src/objects/properties/text_property.hpp b/src/objects/properties/text_property.hpp index 3816f35..3a5d163 100644 --- a/src/objects/properties/text_property.hpp +++ b/src/objects/properties/text_property.hpp @@ -1,8 +1,8 @@ -// -// Created by Jonathan Purol on 26.11.23. -// +#pragma once -#ifndef TEXT_PROPERTY_HPP -#define TEXT_PROPERTY_HPP +#include -#endif //TEXT_PROPERTY_HPP +struct IkarusTextProperty final : IkarusProperty { +public: + IkarusTextProperty(struct IkarusProject * project, IkarusId id); +}; diff --git a/src/objects/properties/toggle_property.cpp b/src/objects/properties/toggle_property.cpp index e69de29..d2fb82d 100644 --- a/src/objects/properties/toggle_property.cpp +++ b/src/objects/properties/toggle_property.cpp @@ -0,0 +1,6 @@ +#include "toggle_property.hpp" + +IkarusToggleProperty::IkarusToggleProperty(IkarusProject * project, IkarusId id): + IkarusProperty{project, id, this} { + +} diff --git a/src/objects/properties/toggle_property.hpp b/src/objects/properties/toggle_property.hpp index 5514d8b..2ca2520 100644 --- a/src/objects/properties/toggle_property.hpp +++ b/src/objects/properties/toggle_property.hpp @@ -3,5 +3,6 @@ #include struct IkarusToggleProperty final : IkarusProperty { +public: IkarusToggleProperty(struct IkarusProject * project, IkarusId id); }; diff --git a/src/persistence/function_context.cpp b/src/persistence/function_context.cpp index 6e252dc..96edddf 100644 --- a/src/persistence/function_context.cpp +++ b/src/persistence/function_context.cpp @@ -14,5 +14,5 @@ FunctionContext::~FunctionContext() { _project->error_infos = {}; } - _project->_function_contexts.pop(); + _project->_function_contexts.pop_back(); } diff --git a/src/persistence/project.cpp b/src/persistence/project.cpp index 3ceb821..d7d5e5e 100644 --- a/src/persistence/project.cpp +++ b/src/persistence/project.cpp @@ -2,6 +2,9 @@ #include "ikarus/persistence/project.h" +#include +#include +#include #include auto IkarusProject::get_name() const -> std::string_view { @@ -21,11 +24,11 @@ auto IkarusProject::get_db() const -> sqlitecpp::Connection const * { } auto IkarusProject::get_function_context() -> FunctionContext * { - return &_function_contexts.emplace(this); + return &_function_contexts.emplace_back(this); } IkarusBlueprint * IkarusProject::get_blueprint(IkarusId id) { - return get_cached_object(id, this->_blueprints); + return get_cached_object(id, this->_blueprints); } auto IkarusProject::uncache_blueprint(IkarusBlueprint * blueprint) -> void { @@ -33,15 +36,28 @@ auto IkarusProject::uncache_blueprint(IkarusBlueprint * blueprint) -> void { } auto IkarusProject::get_entity(IkarusId id) -> IkarusEntity * { - return get_cached_object(id, this->_entities); + return get_cached_object(id, this->_entities); } auto IkarusProject::uncache_entity(IkarusEntity * entity) -> void { remove_cached_object(entity, _entities); } -auto IkarusProject::get_property(IkarusId id) -> IkarusProperty * { - return get_cached_object(id, this->_properties); +auto IkarusProject::get_property(IkarusId id, IkarusPropertyType type) -> IkarusProperty * { + auto const iter = _properties.find(id); + + if (iter == _properties.cend()) { + switch (type) { + case IkarusPropertyType_Toggle: + return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); + case IkarusPropertyType_Number: + return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); + case IkarusPropertyType_Text: + return _properties.emplace(id, std::make_unique(this, id)).first->second.get(); + } + } + + return iter->second.get(); } auto IkarusProject::uncache_property(IkarusProperty * property) -> void { diff --git a/src/persistence/project.hpp b/src/persistence/project.hpp index ef69a81..d3fc6a1 100644 --- a/src/persistence/project.hpp +++ b/src/persistence/project.hpp @@ -9,6 +9,11 @@ #include #include +#include + +#include +#include +#include constexpr inline auto MAXIMUM_ERROR_INFOS = 8; @@ -32,18 +37,16 @@ public: [[nodiscard]] auto get_entity(IkarusId id) -> struct IkarusEntity *; auto uncache_entity(struct IkarusEntity * entity) -> void; - [[nodiscard]] auto get_property(IkarusId id) -> struct IkarusProperty *; + [[nodiscard]] auto get_property(IkarusId id, IkarusPropertyType type) -> struct IkarusProperty *; auto uncache_property(struct IkarusProperty * property) -> void; private: template - [[nodiscard]] T * get_cached_object(IkarusId id, std::unordered_map>& cache) { + [[nodiscard]] T * get_cached_object(IkarusId id, auto& cache) { auto const iter = cache.find(id); if (iter == cache.cend()) { - auto [ret_iter, _] = cache.emplace(id, std::make_unique(this, id)); - - return ret_iter->second.get(); + return cache.emplace(id, std::make_unique(this, id)).first->second.get(); } return iter->second.get(); @@ -51,7 +54,7 @@ private: template void remove_cached_object(T * object, std::unordered_map>& cache) { - cache.erase(object->id); + cache.erase(object->get_id()); } private: @@ -68,5 +71,5 @@ private: std::unordered_map> _properties; std::unordered_map> _entities; - std::stack _function_contexts; + std::vector _function_contexts; }; diff --git a/src/values/value.cpp b/src/values/value.cpp index f61f2bb..7528ec8 100644 --- a/src/values/value.cpp +++ b/src/values/value.cpp @@ -9,6 +9,25 @@ #include #include +IkarusValue::IkarusValue(Data data): + _data(data) {} + +bool IkarusValue::is_interminate() const { + return _indeterminate; +} + +void IkarusValue::set_intermediate(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_interminate(); } @@ -20,9 +39,9 @@ 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->value ? "true" : "false"; }, - [](IkarusNumberValue const * number_value) -> std::string { return fmt::format("{}", number_value->value); }, - [](IkarusTextValue const * text_value) -> std::string { return fmt::format("{}", text_value->value); }, + [](IkarusToggleValue const * toggle_value) -> std::string { return toggle_value->get_value() ? "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() ); diff --git a/src/values/value.hpp b/src/values/value.hpp index 0adc61c..ddf6601 100644 --- a/src/values/value.hpp +++ b/src/values/value.hpp @@ -4,11 +4,10 @@ struct IkarusValue { public: - using Data = std::variant::variant; + using Data = std::variant; public: - explicit IkarusValue(Data data): - _data(data) {} + explicit IkarusValue(Data data); IkarusValue(IkarusValue const&) = default; IkarusValue(IkarusValue&&) noexcept = default; @@ -16,24 +15,14 @@ public: IkarusValue& operator=(IkarusValue const&) = default; IkarusValue& operator=(IkarusValue&&) noexcept = default; - virtual ~IkarusValue(); + virtual ~IkarusValue() = default; public: - [[nodiscard]] inline bool is_interminate() const { - return _indeterminate; - } + [[nodiscard]] bool is_interminate() const; + void set_intermediate(bool value); - void set_intermediate(bool value) { - _indeterminate = value; - } - - [[nodiscard]] inline Data& get_data() { - return _data; - } - - [[nodiscard]] inline Data const& get_data() const { - return _data; - } + [[nodiscard]] Data& get_data(); + [[nodiscard]] Data const& get_data() const; private: bool _indeterminate{false};