diff --git a/src/ifcparse/IfcEntityInstanceData.cpp b/src/ifcparse/IfcEntityInstanceData.cpp index 5a1c0905bf..14e5864d9c 100644 --- a/src/ifcparse/IfcEntityInstanceData.cpp +++ b/src/ifcparse/IfcEntityInstanceData.cpp @@ -73,7 +73,9 @@ namespace { return array_.storage_ptr->index(index_); } else { std::string str; - array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (is_entity ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str); + if (!array_.db_ptr->db->Get(rocksdb::ReadOptions{}, (is_entity ? "i|" : "t|") + std::to_string(instance_name_) + "|" + std::to_string(index_), &str).ok()) { + return TypeEncoder::encode_type() - 'A'; + } return (size_t) str[0] - 'A'; } } diff --git a/src/ifcparse/IfcEntityInstanceData.h b/src/ifcparse/IfcEntityInstanceData.h index e4d13eb2b2..92e006fef2 100644 --- a/src/ifcparse/IfcEntityInstanceData.h +++ b/src/ifcparse/IfcEntityInstanceData.h @@ -334,6 +334,54 @@ struct AttributeValue { unsigned int size() const; IfcUtil::ArgumentType type() const; + + template + auto apply_visitor(Visitor&& visitor) const { + switch (type()) { + case IfcUtil::Argument_DERIVED: + return visitor(Derived{}); + case IfcUtil::Argument_INT: + return visitor((int)*this); + case IfcUtil::Argument_BOOL: + return visitor((bool)*this); + case IfcUtil::Argument_LOGICAL: { + boost::logic::tribool tb = *this; + return visitor(tb); + } + case IfcUtil::Argument_DOUBLE: + return visitor((double)*this); + case IfcUtil::Argument_STRING: + return visitor((std::string)*this); + case IfcUtil::Argument_BINARY: + return visitor((boost::dynamic_bitset<>)*this); + case IfcUtil::Argument_ENUMERATION: + return visitor((EnumerationReference)*this); + case IfcUtil::Argument_ENTITY_INSTANCE: + return visitor((IfcUtil::IfcBaseClass*)*this); + case IfcUtil::Argument_AGGREGATE_OF_INT: + return visitor((std::vector)*this); + case IfcUtil::Argument_AGGREGATE_OF_DOUBLE: + return visitor((std::vector)*this); + case IfcUtil::Argument_AGGREGATE_OF_STRING: + return visitor((std::vector)*this); + case IfcUtil::Argument_AGGREGATE_OF_BINARY: + return visitor((std::vector>)*this); + case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: + return visitor((boost::shared_ptr)*this); + case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT: + return visitor((std::vector>)*this); + case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE: + return visitor((std::vector>)*this); + case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: + return visitor((boost::shared_ptr)*this); + case IfcUtil::Argument_EMPTY_AGGREGATE: + return visitor(empty_aggregate_t{}); + case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE: + return visitor(empty_aggregate_of_aggregate_t{}); + default: + return visitor(Blank{}); + } + } }; struct rocks_db_attribute_storage { diff --git a/src/ifcparse/IfcFile.cpp b/src/ifcparse/IfcFile.cpp index 98dbe8af58..131aceba9c 100644 --- a/src/ifcparse/IfcFile.cpp +++ b/src/ifcparse/IfcFile.cpp @@ -344,7 +344,7 @@ IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::rocksdb_instance_i } */ -const IfcParse::declaration* IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::operator*() const { +IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::value_type const& IfcParse::impl::rocks_db_file_storage::rocksdb_types_iterator::operator*() const { return storage_->file->schema()->declarations()[*read_id_()]; } diff --git a/src/ifcparse/IfcFile.h b/src/ifcparse/IfcFile.h index c1a244f117..c4c9ad72a2 100644 --- a/src/ifcparse/IfcFile.h +++ b/src/ifcparse/IfcFile.h @@ -135,6 +135,8 @@ struct parse_context { #include #include +#ifndef SWIG + template class variant_iterator { public: @@ -211,6 +213,8 @@ private: variant_type it_; }; +#endif + namespace impl { struct in_memory_file_storage { IfcParse::IfcSpfLexer* tokens; @@ -236,7 +240,7 @@ namespace impl { in_memory_file_storage(const in_memory_file_storage&) = delete; in_memory_file_storage(const in_memory_file_storage&&) = delete; - class type_iterator : private entities_by_type_t::const_iterator { + class type_iterator : public entities_by_type_t::const_iterator { public: using iterator_category = std::forward_iterator_tag; using value_type = entities_by_type_t::key_type; @@ -267,12 +271,6 @@ namespace impl { operator++(); return tmp; } - - bool operator!=(const type_iterator& other) const { - const entities_by_type_t::const_iterator& self_ = *this; - const entities_by_type_t::const_iterator& other_ = other; - return self_ != other_; - } }; @@ -547,7 +545,11 @@ namespace impl { return !(*this == other); } - const IfcParse::declaration* operator*() const; + value_type const& operator*() const; + + value_type const* operator->() const { + return &operator*(); + } }; // @todo rocksdb_instance_iterator? diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index 8e921ff856..7e01a5ad0f 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -2310,12 +2310,11 @@ IfcUtil::IfcBaseClass* IfcFile::instance_by_guid(const std::string& guid) { IfcFile::type_iterator IfcFile::types_begin() const { return std::visit([](const auto& x) { if constexpr (std::is_same_v, std::monostate>) { - throw std::runtime_error("Storage not initialized"); - return (IfcFile::type_iterator) impl::rocks_db_file_storage::rocksdb_types_iterator{}; + return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator{} }; } else if constexpr (std::is_same_v, impl::in_memory_file_storage>) { - return (IfcFile::type_iterator) x.bytype_excl_.begin(); + return IfcFile::type_iterator{ x.bytype_excl_.begin() }; } else if constexpr (std::is_same_v, impl::rocks_db_file_storage>) { - return (IfcFile::type_iterator) impl::rocks_db_file_storage::rocksdb_types_iterator(&x); + return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator(&x) }; } }, storage_); } @@ -2323,12 +2322,11 @@ IfcFile::type_iterator IfcFile::types_begin() const { IfcFile::type_iterator IfcFile::types_end() const { return std::visit([](const auto& x) { if constexpr (std::is_same_v, std::monostate>) { - throw std::runtime_error("Storage not initialized"); - return (IfcFile::type_iterator)impl::rocks_db_file_storage::rocksdb_types_iterator{}; + return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator{} }; } else if constexpr (std::is_same_v, impl::in_memory_file_storage>) { - return (IfcFile::type_iterator)x.bytype_excl_.end(); + return IfcFile::type_iterator{ x.bytype_excl_.end() }; } else if constexpr (std::is_same_v, impl::rocks_db_file_storage>) { - return (IfcFile::type_iterator)impl::rocks_db_file_storage::rocksdb_types_iterator{}; + return IfcFile::type_iterator{ impl::rocks_db_file_storage::rocksdb_types_iterator{} }; } }, storage_); } diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index b7af4036bf..53678b42e7 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -29,6 +29,13 @@ private: %ignore IfcParse::IfcFile::schema; %ignore IfcParse::IfcFile::begin; %ignore IfcParse::IfcFile::end; +%ignore IfcParse::IfcFile::types_begin; +%ignore IfcParse::IfcFile::types_end; +%ignore IfcParse::IfcFile::internal_guid_map; +%ignore IfcParse::IfcFile::storage_; + +%ignore in_memory_file_storage; +%ignore rocks_db_file_storage; %ignore parse_context; @@ -154,7 +161,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas std::vector entity_names() const { std::vector keys; keys.reserve(std::distance($self->begin(), $self->end())); - for (IfcParse::IfcFile::entity_by_id_t::const_iterator it = $self->begin(); it != $self->end(); ++ it) { + for (auto it = $self->begin(); it != $self->end(); ++ it) { keys.push_back(it->first); } return keys; @@ -286,7 +293,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas } AttributeValue get_argument(unsigned i) { - return $self->data().get_attribute_value(i); + return $self->get_attribute_value(i); } AttributeValue get_argument(const std::string& a) { @@ -294,7 +301,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas if (i == -1) { throw std::runtime_error("Attribute '" + a + "' not found on entity named " + $self->declaration().name()); } - return $self->data().get_attribute_value((unsigned)i); + return $self->get_attribute_value((unsigned)i); } bool __eq__(IfcUtil::IfcBaseClass* other) const { @@ -595,7 +602,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas IfcUtil::IfcBaseClass* new_IfcBaseClass(const std::string& schema_identifier, const std::string& name) { const IfcParse::schema_definition* schema = IfcParse::schema_by_name(schema_identifier); const IfcParse::declaration* decl = schema->declaration_by_name(name); - IfcEntityInstanceData data(storage_t(decl->as_entity() ? decl->as_entity()->attribute_count() : 1)); + IfcEntityInstanceData data(in_memory_attribute_storage(decl->as_entity() ? decl->as_entity()->attribute_count() : 1)); auto inst = schema->instantiate(decl, std::move(data)); if (auto entinst = inst->as()) { entinst->populate_derived(); @@ -763,8 +770,8 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas // @todo refactor this to remove duplication with the typemap. // except this is calls the above function in case of instances. - PyObject* convert_cpp_attribute_to_python(AttributeValue arg, bool include_identifier = true) { - return arg.array_->apply_visitor([include_identifier](auto& v){ + PyObject* convert_cpp_attribute_to_python(IfcUtil::IfcBaseClass* instance, size_t attribute_index, bool include_identifier = true) { + return instance->get_attribute_value(attribute_index).apply_visitor([include_identifier](const auto& v){ using U = std::decay_t; if constexpr (is_std_vector_v) { return pythonize_vector(v); @@ -802,7 +809,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas } else { return pythonize(v); } - }, arg.index_); + }); } %} %inline %{ @@ -819,7 +826,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas auto attr_type = *dit ? IfcUtil::Argument_DERIVED : IfcUtil::from_parameter_type((*it)->type_of_attribute()); - auto value_cpp = v->data().get_attribute_value(std::distance(attrs.begin(), it)); + auto value_cpp = v->get_attribute_value(std::distance(attrs.begin(), it)); auto value_py = convert_cpp_attribute_to_python(value_cpp, include_identifier); PyDict_SetItem(d, name_py, value_py); Py_DECREF(name_py); @@ -836,7 +843,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas } else { const std::string& name_cpp = "wrappedValue"; auto name_py = pythonize(name_cpp); - auto value_cpp = v->data().get_attribute_value(0); + auto value_cpp = v->get_attribute_value(0); auto value_py = convert_cpp_attribute_to_python(value_cpp, include_identifier); PyDict_SetItem(d, name_py, value_py); Py_DECREF(name_py); diff --git a/src/ifcwrap/utils/typemaps_out.i b/src/ifcwrap/utils/typemaps_out.i index 1c9761e4fe..1e8a947fac 100644 --- a/src/ifcwrap/utils/typemaps_out.i +++ b/src/ifcwrap/utils/typemaps_out.i @@ -36,7 +36,7 @@ // of our typemap. So the attribute conversion block // is wrapped in a try-catch block manually. try { - $result = $1.array_->apply_visitor([](auto& v){ + $result = $1.apply_visitor([](const auto& v){ using U = std::decay_t; if constexpr (is_std_vector_v) { return pythonize_vector(v); @@ -58,7 +58,7 @@ } else { return pythonize(v); } - }, $1.index_); + }); } catch(IfcParse::IfcException& e) { SWIG_exception(SWIG_RuntimeError, e.what()); } catch(...) { diff --git a/src/serializers/RocksDbSerializer.cpp b/src/serializers/RocksDbSerializer.cpp index c99f450f6f..0bf4a83642 100644 --- a/src/serializers/RocksDbSerializer.cpp +++ b/src/serializers/RocksDbSerializer.cpp @@ -14,7 +14,7 @@ RocksDbSerializer::RocksDbSerializer(IfcParse::IfcFile* file, const std::string& options.create_if_missing = true; options.merge_operator.reset(new ConcatenateIdMergeOperator()); rocksdb::Status status = rocksdb::DB::Open(options, rocksdb_filename, &db_);*/ - output_file_ = new IfcParse::IfcFile(file_->schema(), IfcParse::rocksdb, rocksdb_filename_); + output_file_ = new IfcParse::IfcFile(file_->schema(), IfcParse::FT_ROCKSDB, rocksdb_filename_); } void RocksDbSerializer::finalize() diff --git a/win/build-deps.cmd b/win/build-deps.cmd index 1f9581e652..c93798c3ef 100644 --- a/win/build-deps.cmd +++ b/win/build-deps.cmd @@ -516,12 +516,12 @@ IF EXIST "%INSTALL_DIR%\swigwin" ( goto :cgal ) -set SWIG_VERSION=3.0.12 +set SWIG_VERSION=4.3.0 set DEPENDENCY_NAME=SWIG %SWIG_VERSION% set DEPENDENCY_DIR=N/A set SWIG_ZIP=swigwin-%SWIG_VERSION%.zip cd "%DEPS_DIR%" -call :DownloadFile https://github.com/aothms/swigwin-3.0.12/raw/refs/heads/main/swigwin-3.0.12.zip "%DEPS_DIR%" %SWIG_ZIP% +call :DownloadFile https://sourceforge.net/projects/swig/files/swigwin/swigwin-%SWIG_VERSION%/%SWIG_ZIP% "%DEPS_DIR%" %SWIG_ZIP% IF NOT %ERRORLEVEL%==0 GOTO :Error call :ExtractArchive %SWIG_ZIP% "%DEPS_DIR%" "%DEPS_DIR%\swigwin" IF NOT %ERRORLEVEL%==0 GOTO :Error