diff --git a/src/ifcparse/IfcEntityInstanceData.cpp b/src/ifcparse/IfcEntityInstanceData.cpp index 14e5864d9c..0c79314327 100644 --- a/src/ifcparse/IfcEntityInstanceData.cpp +++ b/src/ifcparse/IfcEntityInstanceData.cpp @@ -350,6 +350,26 @@ bool impl::deserialize(IfcParse::impl::rocks_db_file_storage*, const std::string return false; } +template +bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const +{ + // @todo unify with other implementation functions + const bool is_header = decl->schema() == &Header_section_schema::get_schema(); + IfcParse::impl::rocks_db_file_storage* rdb_storage = (IfcParse::impl::rocks_db_file_storage*)storage; + std::string v; + auto success = rdb_storage->db->Get( + rocksdb::ReadOptions{}, + (is_header ? "h|" : (decl->as_entity() ? "i|" : "t|")) + + (is_header ? decl->name() : std::to_string(identity)) + "|" + + std::to_string(index), &v); + if constexpr (std::is_same_v, Blank>) { + if (!success.ok()) { + return true; + } + } + return v.size() && v[0] == TypeEncoder::encode_type(); +} + template void rocks_db_attribute_storage::set(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, const T& value) { @@ -386,3 +406,28 @@ template void rocks_db_attribute_storage::set(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const Derived& value); template void rocks_db_attribute_storage::set(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_t& value); template void rocks_db_attribute_storage::set(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_of_aggregate_t& value); + + + +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; + +// @todo why do these need to be included, but are not in BaseEntity::set()? +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; +template bool rocks_db_attribute_storage::has(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const; diff --git a/src/ifcparse/IfcEntityInstanceData.h b/src/ifcparse/IfcEntityInstanceData.h index 92e006fef2..cfcb466af5 100644 --- a/src/ifcparse/IfcEntityInstanceData.h +++ b/src/ifcparse/IfcEntityInstanceData.h @@ -385,17 +385,6 @@ struct AttributeValue { }; struct rocks_db_attribute_storage { -private: - template - auto apply_visitor_impl(Visitor&& visitor, std::size_t idx, std::integral_constant) const { - return apply_visitor_impl(std::forward(visitor), idx, std::integral_constant{}); - } - - template - void apply_visitor_impl(Visitor&&, std::size_t, std::integral_constant) const { - throw std::runtime_error("Invalid variant index"); - } - public: size_t size(void*, const IfcParse::declaration*, std::size_t identity) const { // @todo is this actually needed? @@ -407,14 +396,12 @@ public: void set(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, const T& value); template - bool has(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index) const { - // @todo - return false; - } + bool has(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const; template - auto apply_visitor(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, Visitor&& visitor) const { - return apply_visitor_impl(std::forward(visitor), index, std::integral_constant{}); + auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, Visitor&& visitor) const { + // @todo do we need visitation on all data/storage/attribute levels? + AttributeValue((IfcParse::impl::rocks_db_file_storage*)storage, identity, decl->as_entity() ? 1 : 0, index).apply_visitor(std::forward(visitor)); } };