Merge remote-tracking branch 'origin/v0.8.0' into tfk-rocksdb-storage

This commit is contained in:
Thomas Krijnen
2025-08-26 10:17:57 +02:00
1179 changed files with 47255 additions and 16166 deletions
+14 -40
View File
@@ -24,6 +24,8 @@
* *
********************************************************************************/
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#include "IfcCharacterDecoder.h"
#include "IfcException.h"
@@ -35,6 +37,7 @@
#include <sstream>
#include <string>
#include <algorithm>
#include <boost/locale.hpp>
#define FIRST_SOLIDUS (1 << 1)
#define PAGE (1 << 2)
@@ -90,7 +93,7 @@ class pure_impure_helper {
bool pure_;
IfcParse::IfcSpfStream* stream_;
unsigned int& pointer_;
std::wstring builder_;
std::u32string builder_;
char peek() {
if (pure_) {
@@ -223,7 +226,7 @@ class pure_impure_helper {
if (mode == IfcParse::IfcCharacterDecoder::SUBSTITUTE) {
std::string result;
result.reserve(builder_.size());
std::transform(builder_.begin(), builder_.end(), std::back_inserter(result), [&substitution_character](wchar_t character) {
std::transform(builder_.begin(), builder_.end(), std::back_inserter(result), [&substitution_character](std::u32string::value_type character) {
if (character >= 0x20 && character <= 0x7e) {
return (char)character;
}
@@ -234,7 +237,7 @@ class pure_impure_helper {
if (mode == IfcParse::IfcCharacterDecoder::ESCAPE) {
std::stringstream stream;
stream << std::hex << std::setw(4) << std::setfill('0');
std::for_each(builder_.begin(), builder_.end(), [&stream](wchar_t character) {
std::for_each(builder_.begin(), builder_.end(), [&stream](std::u32string::value_type character) {
if (character >= 0x20 && character <= 0x7e) {
stream.put((char)character);
} else {
@@ -327,7 +330,7 @@ IfcCharacterDecoder::ConversionMode IfcCharacterDecoder::mode = IfcCharacterDeco
char IfcCharacterDecoder::substitution_character = '_';
IfcCharacterEncoder::IfcCharacterEncoder(const std::string& input)
: str_(IfcUtil::convert_utf8_to_utf32(input)) {}
: str_(IfcUtil::convert_utf8(input)) {}
IfcCharacterEncoder::operator std::string() {
std::ostringstream oss;
@@ -337,7 +340,7 @@ IfcCharacterEncoder::operator std::string() {
// Currently hardcoded to 4, but \X2 might be
// sufficient for nearly all purposes.
const int num_bytes = (str_.empty() || (*std::max_element(str_.begin(), str_.end()) > 0xffff)) ? 4 : 2;
const std::string num_bytes_str = std::string(1, num_bytes + 0x30);
const std::string num_bytes_str = std::string(1, (char) (num_bytes + 0x30));
bool in_extended = false;
@@ -382,7 +385,7 @@ def _():
"{%s}" % ",".join(_())
*/
std::wstring::value_type IfcUtil::convert_codepage(int codepage, int character) {
std::u32string::value_type IfcUtil::convert_codepage(int codepage, int character) {
if (codepage < 1 || codepage > 16 || codepage == 12) {
throw IfcParse::IfcException("Invalid codepage");
}
@@ -390,7 +393,7 @@ std::wstring::value_type IfcUtil::convert_codepage(int codepage, int character)
throw IfcParse::IfcException("Invalid character ordinal");
}
// NOLINTBEGIN(readability-magic-numbers)
static std::array<std::array<wchar_t, 256>, 16> codepage_data = {{{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}},
static std::array<std::array<std::u32string::value_type, 256>, 16> codepage_data = {{{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 728, 321, 164, 317, 346, 167, 168, 352, 350, 356, 377, 173, 381, 379, 176, 261, 731, 322, 180, 318, 347, 711, 184, 353, 351, 357, 378, 733, 382, 380, 340, 193, 194, 258, 196, 313, 262, 199, 268, 201, 280, 203, 282, 205, 206, 270, 272, 323, 327, 211, 212, 336, 214, 215, 344, 366, 218, 368, 220, 221, 354, 223, 341, 225, 226, 259, 228, 314, 263, 231, 269, 233, 281, 235, 283, 237, 238, 271, 273, 324, 328, 243, 244, 337, 246, 247, 345, 367, 250, 369, 252, 253, 355, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 294, 728, 163, 164, 0, 292, 167, 168, 304, 350, 286, 308, 173, 0, 379, 176, 295, 178, 179, 180, 181, 293, 183, 184, 305, 351, 287, 309, 189, 0, 380, 192, 193, 194, 0, 196, 266, 264, 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, 209, 210, 211, 212, 288, 214, 215, 284, 217, 218, 219, 220, 364, 348, 223, 224, 225, 226, 0, 228, 267, 265, 231, 232, 233, 234, 235, 236, 237, 238, 239, 0, 241, 242, 243, 244, 289, 246, 247, 285, 249, 250, 251, 252, 365, 349, 729}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 260, 312, 342, 164, 296, 315, 167, 168, 352, 274, 290, 358, 173, 381, 175, 176, 261, 731, 343, 180, 297, 316, 711, 184, 353, 275, 291, 359, 330, 382, 331, 256, 193, 194, 195, 196, 197, 198, 302, 268, 201, 280, 203, 278, 205, 206, 298, 272, 325, 332, 310, 212, 213, 214, 215, 216, 370, 218, 219, 220, 360, 362, 223, 257, 225, 226, 227, 228, 229, 230, 303, 269, 233, 281, 235, 279, 237, 238, 299, 273, 326, 333, 311, 244, 245, 246, 247, 248, 371, 250, 251, 252, 361, 363, 729}},
@@ -414,19 +417,11 @@ std::wstring::value_type IfcUtil::convert_codepage(int codepage, int character)
return result;
}
std::string IfcUtil::convert_utf8(const std::wstring& string) {
return std::wstring_convert<std::codecvt_utf8<std::wstring::value_type>>().to_bytes(string);
std::string IfcUtil::convert_utf8(const std::u32string& string) {
return boost::locale::conv::utf_to_utf<char>(string);
}
std::wstring IfcUtil::convert_utf8(const std::string& string) {
return std::wstring_convert<std::codecvt_utf8<std::wstring::value_type>>().from_bytes(string);
}
#ifdef _MSC_VER
// bug in msvc 2015 and 2017, unsure if fixed in later versions
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
std::u32string IfcUtil::convert_utf8(const std::string& s) {
bool is_ascii = true;
for (char c : s) {
if (static_cast<unsigned char>(c) >= 128) {
@@ -436,27 +431,6 @@ std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
}
if (is_ascii) {
return std::u32string(s.begin(), s.end());
} else {
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
return std::u32string(reinterpret_cast<char32_t const*>(converted.data()));
}
return boost::locale::conv::utf_to_utf<char32_t>(s);
}
#else
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
bool is_ascii = true;
for (char c : s) {
if (static_cast<unsigned char>(c) >= 128) {
is_ascii = false;
break;
}
}
if (is_ascii) {
return std::u32string(s.begin(), s.end());
}
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(s);
}
#endif
+3 -4
View File
@@ -32,10 +32,9 @@
#include <string>
namespace IfcUtil {
std::wstring::value_type convert_codepage(int codepage, int index);
std::string convert_utf8(const std::wstring& string);
std::wstring convert_utf8(const std::string& string);
std::u32string convert_utf8_to_utf32(const std::string& string);
std::u32string::value_type convert_codepage(int codepage, int index);
std::string convert_utf8(const std::u32string& string);
std::u32string convert_utf8(const std::string& string);
} // namespace IfcUtil
namespace IfcParse {
+7 -7
View File
@@ -225,7 +225,7 @@ namespace {
}
}
IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size) {
IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size, int resolve_reference_index) {
std::vector<const IfcParse::parameter_type*> parameter_types;
std::unique_ptr<IfcParse::named_type> transient_named_type;
@@ -274,16 +274,16 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
auto index = (uint8_t) std::distance(tokens_.begin(), it);
std::visit([this, &storage, name, &references_to_resolve, index, param_type](const auto& v) {
std::visit([this, &storage, name, &references_to_resolve, index, param_type, resolve_reference_index](const auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
dispatch_token(name, index, v, param_type && param_type->as_named_type() ? param_type->as_named_type()->declared_type() : nullptr, [this, &storage, name, &references_to_resolve, index](auto v) {
dispatch_token(name, index, v, param_type && param_type->as_named_type() ? param_type->as_named_type()->declared_type() : nullptr, [this, &storage, name, &references_to_resolve, index, resolve_reference_index](auto v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::reference_or_simple_type>) {
if (name > 0) {
references_to_resolve.push_back(std::make_pair(
// @todo previously this was storage but apparently the
// pointer is not constant with the moving and temporary nature
// maybe it ought to be and in that case a pointer is more direct
MutableAttributeValue{ name, index },
MutableAttributeValue{ name, resolve_reference_index == -1 ? index : (uint8_t) resolve_reference_index },
v
));
}
@@ -298,14 +298,14 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
pt = pt->as_named_type()->declared_type()->as_type_declaration()->declared_type();
}
}
construct_<0>(name, index, *v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const auto& v) {
construct_<0>(name, index, *v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index, resolve_reference_index](const auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
if (name > 0) {
references_to_resolve.push_back({ {name, index }, v });
references_to_resolve.push_back({ {name, resolve_reference_index == -1 ? index : (uint8_t)resolve_reference_index }, v });
}
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<std::vector<reference_or_simple_type>>>) {
if (name > 0) {
references_to_resolve.push_back({ {name, index }, v });
references_to_resolve.push_back({ {name, resolve_reference_index == -1 ? index : (uint8_t)resolve_reference_index }, v });
}
} else {
storage.set(index, v);
+1 -3
View File
@@ -175,9 +175,7 @@ public:
/// This class provides access to the entity instances in an IFC file
/// The file takes ownership of instances added to this file and deletes them when the file is deleted.
class IFC_PARSE_API IfcFile {
public:
private:
private:
typedef std::map<uint32_t, IfcUtil::IfcBaseClass*> entity_entity_map_t;
// @todo determine the constness of things (probably needs to be all const, we don't want to overwrite)
+8
View File
@@ -330,6 +330,10 @@ aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_add2::IfcRelAggregate
return t->RelatedObjects()->generalize();
}
aggregate_of_instance::ptr get_children_of_relation(Ifc4x3_add2::IfcRelNests* t) {
return t->RelatedObjects()->generalize();
}
void set_children_of_relation(Ifc4x3_add2::IfcRelContainedInSpatialStructure* t, aggregate_of_instance::ptr& cs) {
t->setRelatedElements(cs->as<Ifc4x3_add2::IfcProduct>());
}
@@ -337,6 +341,10 @@ void set_children_of_relation(Ifc4x3_add2::IfcRelContainedInSpatialStructure* t,
void set_children_of_relation(Ifc4x3_add2::IfcRelAggregates* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_add2::IfcObjectDefinition>());
}
void set_children_of_relation(Ifc4x3_add2::IfcRelNests* t, aggregate_of_instance::ptr& cs) {
t->setRelatedObjects(cs->as<Ifc4x3_add2::IfcObjectDefinition>());
}
#endif
IfcUtil::IfcBaseClass* get_parent_of_relation(IfcUtil::IfcBaseClass* t) {
+61 -5
View File
@@ -717,8 +717,14 @@ void IfcParse::impl::in_memory_file_storage::load(unsigned entity_instance_name,
const auto* decl = (schema ? schema : file->schema())->declaration_by_name(TokenFunc::asStringRef(next));
parse_context ps;
tokens->Next();
load(0, nullptr, ps, -1);
auto* simple_type_instance = (schema ? schema : file->schema())->instantiate(decl, ps.construct(-1, *references_to_resolve, decl, boost::none));
// The only case we know where a defined type contains entity
// instance references is IfcPropertySetDefinitionSet. For
// that purpose we propagate the entity_instance_name to
// register inverses to the host entity (and not the defined
// type) and to be able to actually register the references in
// the 2nd pass.
load(entity_instance_name, entity, ps, attribute_index == -1 ? (int)attribute_index_within_data : attribute_index);
auto* simple_type_instance = (schema ? schema : file->schema())->instantiate(decl, ps.construct(entity_instance_name, references_to_resolve, decl, boost::none, attribute_index == -1 ? (int)attribute_index_within_data : attribute_index));
//@todo decide addEntity(((IfcUtil::IfcBaseClass*)*entity));
context.push(simple_type_instance);
simple_type_instance->file_ = file;
@@ -1527,7 +1533,23 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::IfcSpfSt
if (it == byid_.end()) {
Logger::Error("Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset));
} else {
byid_[p.first.name_]->data().set_attribute_value(nullptr, nullptr, 0, p.first.index_, it->second);
auto* storage = &byid_[p.first.name_]->data();
auto attr_index = p.first.index_;
if (storage->has_attribute_value<IfcUtil::IfcBaseClass*>(nullptr, nullptr, 0, attr_index)) {
auto inst = storage->get_attribute_value<IfcUtil::IfcBaseClass*>(nullptr, nullptr, 0, attr_index);
if (!inst->declaration().as_entity()) {
// Probably a case of IfcPropertySetDefinitionSet, divert storage of reference to the simply type instance
storage = &inst->data();
attr_index = 0;
}
}
if (storage->has_attribute_value<Blank>(nullptr, nullptr, 0, attr_index)) {
storage->set(nullptr, nullptr, 0, attr_index, it->second);
} else {
Logger::Error("Duplicate definition for instance reference");
}
}
} else if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(v)) {
byid_[p.first.name_]->data().set_attribute_value(nullptr, nullptr, 0, p.first.index_, *inst);
@@ -1547,7 +1569,24 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::IfcSpfSt
instances->push(*inst);
}
}
byid_[p.first.name_]->data().set_attribute_value(nullptr, nullptr, 0, p.first.index_, instances);
auto* storage = &byid_[p.first.name_]->data();
auto attr_index = p.first.index_;
if (storage->has_attribute_value<IfcUtil::IfcBaseClass*>(nullptr, nullptr, 0, attr_index)) {
auto inst = storage->get_attribute_value<IfcUtil::IfcBaseClass*>(nullptr, nullptr, 0, attr_index);
if (!inst->declaration().as_entity()) {
// Probably a case of IfcPropertySetDefinitionSet, divert storage of reference to the simply type instance
storage = &inst->data();
attr_index = 0;
}
}
if (storage->has_attribute_value<Blank>(nullptr, nullptr, 0, attr_index)) {
storage->set(nullptr, nullptr, 0, attr_index, instances);
} else {
Logger::Error("Duplicate definition for instance reference");
}
} else if (auto* v = std::get_if<std::vector<std::vector<reference_or_simple_type>>>(&p.second)) {
aggregate_of_aggregate_of_instance::ptr instances(new aggregate_of_aggregate_of_instance);
for (const auto& vi : *v) {
@@ -1566,7 +1605,24 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::IfcSpfSt
}
instances->push(inner);
}
byid_[p.first.name_]->data().set_attribute_value(nullptr, nullptr, 0, p.first.index_, instances);
auto* storage = &byid_[p.first.name_]->data();
auto attr_index = p.first.index_;
if (storage->has_attribute_value<IfcUtil::IfcBaseClass*>(nullptr, nullptr, 0, attr_index)) {
auto inst = storage->get_attribute_value<IfcUtil::IfcBaseClass*>(nullptr, nullptr, 0, attr_index);
if (!inst->declaration().as_entity()) {
// Probably a case of IfcPropertySetDefinitionSet, divert storage of reference to the simply type instance
storage = &inst->data();
attr_index = 0;
}
}
if (storage->has_attribute_value<Blank>(nullptr, nullptr, 0, attr_index)) {
storage->set(nullptr, nullptr, 0, attr_index, instances);
} else {
Logger::Error("Duplicate definition for instance reference");
}
}
}
+25 -5
View File
@@ -119,7 +119,7 @@ public:
using TypesTuple = ::impl::MapTypes_t<Types...>;
VariantArray(size_t size)
: size_and_indices_(new uint8_t[size + 1])
: size_and_indices_(size ? new uint8_t[size + 1] : nullptr)
, storage_(size ? new StorageType[size] : nullptr)
{
if (size) {
@@ -161,7 +161,7 @@ public:
void set(std::size_t index, T&& value) {
using U = std::decay_t<T>;
static_assert(::impl::TypeIndex_v<U, Types...> < sizeof...(Types), "Type not supported by variant");
if (index >= size_and_indices_[0]) {
if (index >= size()) {
throw std::out_of_range("Index out of range");
}
@@ -181,12 +181,22 @@ public:
free_();
}
std::size_t index(std::size_t index) const noexcept {
std::size_t index(std::size_t index) const {
if (index >= size()) {
throw IfcParse::IfcException(
"Index " + std::to_string(index) + " is out of range for variant of size " + std::to_string(size())
);
}
return size_and_indices_[index + 1];
}
template<typename T>
T& get(std::size_t index) {
if (index >= size()) {
throw IfcParse::IfcException(
"Index " + std::to_string(index) + " is out of range for variant of size " + std::to_string(size())
);
}
if (!has<T>(index)) {
throw std::bad_cast();
}
@@ -200,11 +210,16 @@ public:
template<typename T>
bool has(std::size_t index) const {
return size_and_indices_[index + 1] == ::impl::TypeIndex<T, Types...>::value;
return index < size() && size_and_indices_[index + 1] == ::impl::TypeIndex<T, Types...>::value;
}
template<typename T>
const T& get(std::size_t index) const {
if (index >= size()) {
throw IfcParse::IfcException(
"Index " + std::to_string(index) + " is out of range for variant of size " + std::to_string(size())
);
}
if (size_and_indices_[index + 1] != ::impl::TypeIndex<T, Types...>::value) {
// @todo this IfcException is silly. Figure out what
// to do, but at the moment it is specifically caught
@@ -224,6 +239,11 @@ public:
template<typename Visitor>
auto apply_visitor(Visitor&& visitor, std::size_t index) const {
if (index >= size()) {
throw IfcParse::IfcException(
"Index " + std::to_string(index) + " is out of range for variant of size " + std::to_string(size())
);
}
return apply_visitor_impl(std::forward<Visitor>(visitor), index, std::integral_constant<std::size_t, sizeof...(Types)>{});
}
@@ -305,4 +325,4 @@ private:
}
};
#endif
#endif