mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
Restructure and rename
This commit is contained in:
@@ -0,0 +1,568 @@
|
||||
#include "instance_data.h"
|
||||
#include "express.h"
|
||||
#include "file.h"
|
||||
|
||||
// @todo is size() still needed?
|
||||
class SizeVisitor {
|
||||
public:
|
||||
typedef int result_type;
|
||||
|
||||
int operator()(const blank& /*i*/) const { return -1; }
|
||||
int operator()(const derived& /*i*/) const { return -1; }
|
||||
int operator()(const int& /*i*/) const { return -1; }
|
||||
int operator()(const bool& /*i*/) const { return -1; }
|
||||
int operator()(const boost::logic::tribool& /*i*/) const { return -1; }
|
||||
int operator()(const double& /*i*/) const { return -1; }
|
||||
int operator()(const std::string& /*i*/) const { return -1; }
|
||||
int operator()(const boost::dynamic_bitset<>& /*i*/) const { return -1; }
|
||||
int operator()(const empty_aggregate_t& /*unused*/) const { return 0; }
|
||||
int operator()(const empty_aggregate_of_aggregate_t& /*unused*/) const { return 0; }
|
||||
int operator()(const std::vector<int>& i) const { return (int)i.size(); }
|
||||
int operator()(const std::vector<double>& i) const { return (int)i.size(); }
|
||||
int operator()(const std::vector<std::vector<int>>& i) const { return (int)i.size(); }
|
||||
int operator()(const std::vector<std::vector<double>>& i) const { return (int)i.size(); }
|
||||
int operator()(const std::vector<std::string>& i) const { return (int)i.size(); }
|
||||
int operator()(const std::vector<boost::dynamic_bitset<>>& i) const { return (int)i.size(); }
|
||||
int operator()(const enumeration_reference& /*i*/) const { return -1; }
|
||||
int operator()(const express::Base& /*i*/) const { return -1; }
|
||||
int operator()(const std::vector<express::Base>& i) const { return (int)i.size(); }
|
||||
int operator()(const std::vector<std::vector<express::Base>>& i) const { return (int)i.size(); }
|
||||
};
|
||||
|
||||
namespace {
|
||||
template<typename T>
|
||||
inline T dispatch_get_(attribute_value::pointer_type array_, uint8_t storage_model_, size_t instance_name_, const ifcopenshell::declaration* entity_or_type, uint8_t index_)
|
||||
{
|
||||
if (storage_model_ == 0) {
|
||||
return array_.storage_ptr->get<T>(index_);
|
||||
}
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
else {
|
||||
T val = T{};
|
||||
const bool is_header = entity_or_type->schema() == &Header_section_schema::get_schema();
|
||||
if constexpr (
|
||||
// the following types cannot be directly deserialized from rocksdb, but need to be constructed
|
||||
!std::is_same_v<T, enumeration_reference> &&
|
||||
!std::is_same_v<std::remove_cv_t<T>, express::Base>)
|
||||
{
|
||||
std::string str;
|
||||
array_.db_ptr->db->Get(rocksdb::ReadOptions{},
|
||||
(is_header ? "h|" : (entity_or_type->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? entity_or_type->name() : std::to_string(instance_name_)) + "|" +
|
||||
std::to_string(index_), &str);
|
||||
impl::deserialize(array_.db_ptr, str, val);
|
||||
} else {
|
||||
static_assert(
|
||||
std::is_same_v<T, enumeration_reference> ||
|
||||
std::is_same_v<std::remove_cv_t<T>, express::Base>,
|
||||
"RocksDB deserialization must be specialized for this enumeration_reference and IfcBaseClass*"
|
||||
);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool dispatch_has_(attribute_value::pointer_type array_, uint8_t storage_model_, size_t instance_name_, const ifcopenshell::declaration* entity_or_type, uint8_t index_)
|
||||
{
|
||||
if (storage_model_ == 0) {
|
||||
return array_.storage_ptr->has<T>(index_);
|
||||
}
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
else {
|
||||
std::string str;
|
||||
const bool is_header = entity_or_type->schema() == &Header_section_schema::get_schema();
|
||||
array_.db_ptr->db->Get(rocksdb::ReadOptions{},
|
||||
(is_header ? "h|" : (entity_or_type->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? entity_or_type->name() : std::to_string(instance_name_)) + "|" +
|
||||
std::to_string(index_), &str);
|
||||
if constexpr (std::is_same_v<T, blank>) {
|
||||
if (str.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return str[0] == TypeEncoder::encode_type<T>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline size_t dispatch_index_(attribute_value::pointer_type array_, uint8_t storage_model_, size_t instance_name_, const ifcopenshell::declaration* entity_or_type, uint8_t index_)
|
||||
{
|
||||
if (storage_model_ == 0) {
|
||||
return array_.storage_ptr->index(index_);
|
||||
}
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
else {
|
||||
std::string str;
|
||||
const bool is_header = entity_or_type->schema() == &Header_section_schema::get_schema();
|
||||
if (!array_.db_ptr->db->Get(rocksdb::ReadOptions{},
|
||||
(is_header ? "h|" : (entity_or_type->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? entity_or_type->name() : std::to_string(instance_name_)) + "|" +
|
||||
std::to_string(index_), &str).ok()) {
|
||||
return TypeEncoder::encode_type<blank>() - 'A';
|
||||
}
|
||||
return (size_t) str[0] - 'A';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
attribute_value::operator int() const
|
||||
{
|
||||
return dispatch_get_<int>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator bool() const
|
||||
{
|
||||
return dispatch_get_<bool>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator double() const
|
||||
{
|
||||
return dispatch_get_<double>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator boost::logic::tribool() const
|
||||
{
|
||||
if (dispatch_has_<bool>(array_, storage_model_, instance_name_, entity_or_type_, index_)) {
|
||||
return dispatch_get_<bool>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
return dispatch_get_<boost::logic::tribool>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::string() const
|
||||
{
|
||||
if (dispatch_has_<enumeration_reference>(array_, storage_model_, instance_name_, entity_or_type_, index_)) {
|
||||
// @todo this is silly, but the way things currently work,
|
||||
// @todo also we don't really need to store a reference to the enumeration type, when this same type is already stored on the definition of the entity and no other value can be provided.
|
||||
if (storage_model_ == 0) {
|
||||
return dispatch_get_<enumeration_reference>(array_, storage_model_, instance_name_, entity_or_type_, index_).value();
|
||||
}
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
else {
|
||||
std::string str;
|
||||
const bool is_header = entity_or_type_->schema() == &Header_section_schema::get_schema();
|
||||
array_.db_ptr->db->Get(rocksdb::ReadOptions{},
|
||||
(is_header ? "h|" : (entity_or_type_->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? entity_or_type_->name() : std::to_string(instance_name_)) + "|" +
|
||||
std::to_string(index_), &str);
|
||||
size_t v;
|
||||
memcpy(&v, str.data() + 1, sizeof(size_t));
|
||||
auto decl = array_.db_ptr->file->schema()->declarations()[v]->as_enumeration_type();
|
||||
memcpy(&v, str.data() + 1 + sizeof(size_t), sizeof(size_t));
|
||||
return decl->lookup_enum_value(v);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return dispatch_get_<std::string>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator enumeration_reference() const
|
||||
{
|
||||
if (storage_model_ == 0) {
|
||||
return dispatch_get_<enumeration_reference>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
else {
|
||||
std::string str;
|
||||
const bool is_header = entity_or_type_->schema() == &Header_section_schema::get_schema();
|
||||
array_.db_ptr->db->Get(rocksdb::ReadOptions{},
|
||||
(is_header ? "h|" : (entity_or_type_->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? entity_or_type_->name() : std::to_string(instance_name_)) + "|" +
|
||||
std::to_string(index_), &str);
|
||||
size_t v;
|
||||
memcpy(&v, str.data() + 1, sizeof(size_t));
|
||||
auto decl = array_.db_ptr->file->schema()->declarations()[v]->as_enumeration_type();
|
||||
memcpy(&v, str.data() + 1 + sizeof(size_t), sizeof(size_t));
|
||||
return enumeration_reference(decl, v);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
attribute_value::operator boost::dynamic_bitset<>() const
|
||||
{
|
||||
return dispatch_get_<boost::dynamic_bitset<>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator express::Base () const
|
||||
{
|
||||
if (storage_model_ == 0) {
|
||||
return dispatch_get_<express::Base>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
else {
|
||||
std::string str;
|
||||
const bool is_header = entity_or_type_->schema() == &Header_section_schema::get_schema();
|
||||
array_.db_ptr->db->Get(rocksdb::ReadOptions{},
|
||||
(is_header ? "h|" : (entity_or_type_->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? entity_or_type_->name() : std::to_string(instance_name_)) + "|" +
|
||||
std::to_string(index_), &str);
|
||||
size_t v;
|
||||
memcpy(&v, str.data() + 2, sizeof(size_t));
|
||||
if (str.size() > 1 && str[1] == 'i') {
|
||||
// entity reference, by #Name
|
||||
return array_.db_ptr->assert_existance(v, ifcopenshell::impl::rocks_db_file_storage::entityinstance_ref);
|
||||
} else if (str.size() > 1 && str[1] == 't') {
|
||||
// type reference by Identity
|
||||
return array_.db_ptr->assert_existance(v, ifcopenshell::impl::rocks_db_file_storage::typedecl_ref);
|
||||
} else {
|
||||
throw std::runtime_error("Invalid data encountered");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<int>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<int>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<double>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<double>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<std::string>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<std::string>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<boost::dynamic_bitset<>>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<boost::dynamic_bitset<>>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<express::Base>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<express::Base>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<std::vector<int>>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<std::vector<int>>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<std::vector<double>>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<std::vector<double>>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
attribute_value::operator std::vector<std::vector<express::Base>>() const
|
||||
{
|
||||
return dispatch_get_<std::vector<std::vector<express::Base>>>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
bool attribute_value::isNull() const
|
||||
{
|
||||
return dispatch_has_<blank>(array_, storage_model_, instance_name_, entity_or_type_, index_);
|
||||
}
|
||||
|
||||
unsigned int attribute_value::size() const
|
||||
{
|
||||
// @todo
|
||||
return array_.storage_ptr->apply_visitor(SizeVisitor{}, index_);
|
||||
}
|
||||
|
||||
ifcopenshell::argument_type attribute_value::type() const
|
||||
{
|
||||
return static_cast<ifcopenshell::argument_type>(dispatch_index_(array_, storage_model_, instance_name_, entity_or_type_, index_));
|
||||
}
|
||||
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
|
||||
bool impl::serialize(std::string& val, const express::Base& t)
|
||||
{
|
||||
auto s = sizeof(size_t);
|
||||
val.resize(s + 2);
|
||||
val[0] = TypeEncoder::encode_type<express::Base>();
|
||||
// 1 = entity - stored by id (entity name)
|
||||
// 2 = type - stored by identity (internal counter in class)
|
||||
val[1] = t.declaration().as_entity() ? 'i' : 't';
|
||||
size_t iden = t.id() ? t.id() : t.identity();
|
||||
memcpy(val.data() + 2, &iden, s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const enumeration_reference& v)
|
||||
{
|
||||
auto s = sizeof(size_t);
|
||||
val.resize(s * 2 + 1);
|
||||
val[0] = TypeEncoder::encode_type<enumeration_reference>();
|
||||
size_t vv = v.enumeration()->index_in_schema();
|
||||
memcpy(val.data() + 1, &vv, sizeof(size_t));
|
||||
vv = v.index();
|
||||
memcpy(val.data() + 1 + sizeof(size_t), &vv, sizeof(size_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const std::vector<express::Base>& t)
|
||||
{
|
||||
// no attempt at alignment
|
||||
val.resize(t.size() * (sizeof(size_t) + 1) + 1);
|
||||
val[0] = TypeEncoder::encode_type<std::vector<express::Base>>();
|
||||
char* ptr = val.data() + 1;
|
||||
for (auto& inst : t) {
|
||||
*ptr = inst.declaration().as_entity() ? 'i' : 't';
|
||||
ptr++;
|
||||
size_t iden = inst.id() ? inst.id() : inst.identity();
|
||||
memcpy(ptr, &iden, sizeof(size_t));
|
||||
ptr += sizeof(size_t);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const std::vector<std::vector<express::Base>>& t)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss.put(TypeEncoder::encode_type<std::vector<std::vector<express::Base>>>());
|
||||
|
||||
auto write_size = [&oss](size_t sz) {
|
||||
std::string size_str;
|
||||
size_str.resize(sizeof(size_t));
|
||||
memcpy(size_str.data(), &sz, sizeof(size_t));
|
||||
oss.write(size_str.data(), size_str.size());
|
||||
};
|
||||
|
||||
// write_size(t->size());
|
||||
|
||||
for (auto& inner : t) {
|
||||
// size of inner aggregate
|
||||
write_size(inner.size() * 9);
|
||||
|
||||
// values
|
||||
for (auto& inst : inner) {
|
||||
char c = inst.declaration().as_entity() ? 'i' : 't';
|
||||
oss.put(c);
|
||||
size_t iden = inst.id() ? inst.id() : inst.identity();
|
||||
std::string iden_str;
|
||||
iden_str.resize(sizeof(size_t));
|
||||
memcpy(iden_str.data(), &iden, sizeof(size_t));
|
||||
oss.write(iden_str.data(), iden_str.size());
|
||||
}
|
||||
}
|
||||
|
||||
val = oss.str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const blank&)
|
||||
{
|
||||
val.resize(1);
|
||||
val[0] = TypeEncoder::encode_type<blank>();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const derived&)
|
||||
{
|
||||
val.resize(1);
|
||||
val[0] = TypeEncoder::encode_type<derived>();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const empty_aggregate_t&)
|
||||
{
|
||||
val.resize(1);
|
||||
val[0] = TypeEncoder::encode_type<empty_aggregate_t>();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const empty_aggregate_of_aggregate_t&)
|
||||
{
|
||||
val.resize(1);
|
||||
val[0] = TypeEncoder::encode_type<empty_aggregate_of_aggregate_t>();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const boost::logic::tribool& t)
|
||||
{
|
||||
char tt = t == boost::logic::indeterminate ? 2 : t ? 1 : 0;
|
||||
val.resize(sizeof(char) + 1);
|
||||
val[0] = TypeEncoder::encode_type<boost::logic::tribool>();
|
||||
memcpy(val.data() + 1, &tt, sizeof(char));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::serialize(std::string& val, const boost::dynamic_bitset<>& t)
|
||||
{
|
||||
std::string tmp;
|
||||
boost::to_string(t, tmp);
|
||||
val = std::string(TypeEncoder::encode_type<boost::dynamic_bitset<>>(), 1) + tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::deserialize(ifcopenshell::impl::rocks_db_file_storage*, const std::string& val, boost::logic::tribool& t) {
|
||||
if (val[0] != TypeEncoder::encode_type<boost::logic::tribool>()) {
|
||||
return false;
|
||||
}
|
||||
if (val[1] == 0) {
|
||||
t = false;
|
||||
} else if (val[1] == 1) {
|
||||
t = true;
|
||||
} else if (val[1] == 2) {
|
||||
t = boost::logic::indeterminate;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::deserialize(ifcopenshell::impl::rocks_db_file_storage*, const std::string& val, boost::dynamic_bitset<>& t) {
|
||||
if (val[0] != TypeEncoder::encode_type<boost::dynamic_bitset<>>()) {
|
||||
return false;
|
||||
}
|
||||
t = boost::dynamic_bitset<>(val.substr(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::deserialize(ifcopenshell::impl::rocks_db_file_storage* storage, const std::string& val, std::vector<express::Base>& t) {
|
||||
auto n = (val.size() - 1) / (sizeof(size_t) + 1);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
auto ptr = val.data() + 1 + (sizeof(size_t) + 1) * i;
|
||||
auto tt = *ptr;
|
||||
ptr++;
|
||||
size_t v;
|
||||
memcpy(&v, ptr, sizeof(size_t));
|
||||
if (tt == 'i') {
|
||||
t.push_back(storage->assert_existance(v, ifcopenshell::impl::rocks_db_file_storage::entityinstance_ref));
|
||||
} else if (tt == 't') {
|
||||
t.push_back(storage->assert_existance(v, ifcopenshell::impl::rocks_db_file_storage::typedecl_ref));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool impl::deserialize(ifcopenshell::impl::rocks_db_file_storage* storage, const std::string& val, std::vector<std::vector<express::Base>>& t) {
|
||||
char const* ptr = val.data() + 1;
|
||||
|
||||
// size_t outer_size;
|
||||
// memcpy(&outer_size, ptr, sizeof(size_t));
|
||||
// ptr += sizeof(size_t);
|
||||
|
||||
while (ptr < val.data() + val.size()) {
|
||||
size_t inner_size;
|
||||
memcpy(&inner_size, ptr, sizeof(size_t));
|
||||
ptr += sizeof(size_t);
|
||||
|
||||
if (ptr + inner_size * (sizeof(size_t) + 1) > val.data() + val.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& inner = t.emplace_back();
|
||||
inner.reserve(inner_size);
|
||||
|
||||
for (size_t i = 0; i < inner_size; ++i) {
|
||||
auto tt = *ptr;
|
||||
ptr++;
|
||||
size_t v;
|
||||
memcpy(&v, ptr, sizeof(size_t));
|
||||
ptr += sizeof(size_t);
|
||||
if (tt == 'i') {
|
||||
inner.push_back(storage->assert_existance(v, ifcopenshell::impl::rocks_db_file_storage::entityinstance_ref));
|
||||
} else if (tt == 't') {
|
||||
inner.push_back(storage->assert_existance(v, ifcopenshell::impl::rocks_db_file_storage::typedecl_ref));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool rocks_db_attribute_storage::has(void* storage, const ifcopenshell::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();
|
||||
ifcopenshell::impl::rocks_db_file_storage* rdb_storage = (ifcopenshell::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<std::decay_t<T>, blank>) {
|
||||
if (!success.ok()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return v.size() && v[0] == TypeEncoder::encode_type<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void rocks_db_attribute_storage::set(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, std::size_t index, const T& value)
|
||||
{
|
||||
const bool is_header = decl->schema() == &Header_section_schema::get_schema();
|
||||
ifcopenshell::impl::rocks_db_file_storage* rdb_storage = (ifcopenshell::impl::rocks_db_file_storage*)storage;
|
||||
std::string v;
|
||||
impl::serialize(v, value);
|
||||
rdb_storage->db->Put(
|
||||
rdb_storage->wopts,
|
||||
(is_header ? "h|" : (decl->as_entity() ? "i|" : "t|")) +
|
||||
(is_header ? decl->name() : std::to_string(identity)) + "|" +
|
||||
std::to_string(index), v);
|
||||
}
|
||||
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<blank>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const blank& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<int>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const int& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<bool>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const bool& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<boost::logic::tribool>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const boost::logic::tribool& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<double>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const double& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::string>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::string& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<boost::dynamic_bitset<>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const boost::dynamic_bitset<>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<enumeration_reference>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const enumeration_reference& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<express::Base>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, express::Base const& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<int>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<int>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<double>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<double>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::string>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<std::string>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<boost::dynamic_bitset<>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<boost::dynamic_bitset<>>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<express::Base>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<express::Base>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::vector<int>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<int>>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::vector<double>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<double>>& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::vector<express::Base>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<express::Base>>& value);
|
||||
|
||||
// @todo why do these need to be included, but are not in BaseEntity::set()?
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<derived>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const derived& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<empty_aggregate_t>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_t& value);
|
||||
template IFC_PARSE_API void rocks_db_attribute_storage::set<empty_aggregate_of_aggregate_t>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_of_aggregate_t& value);
|
||||
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<blank>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<int>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<bool>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<boost::logic::tribool>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<double>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::string>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<boost::dynamic_bitset<>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<enumeration_reference>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<express::Base>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<int>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<double>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::string>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<boost::dynamic_bitset<>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<express::Base>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::vector<int>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::vector<double>>>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::vector<express::Base>>>(void* storage, const ifcopenshell::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 IFC_PARSE_API bool rocks_db_attribute_storage::has<derived>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<empty_aggregate_t>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
template IFC_PARSE_API bool rocks_db_attribute_storage::has<empty_aggregate_of_aggregate_t>(void* storage, const ifcopenshell::declaration* decl, std::size_t identity, size_t index) const;
|
||||
|
||||
template <typename T>
|
||||
T* instance_data::get_storage_of_type() const {
|
||||
return std::visit([this](auto& m) -> T* {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(m)>, T>) {
|
||||
return &m;
|
||||
}
|
||||
return nullptr;
|
||||
}, file()->storage_);
|
||||
}
|
||||
|
||||
template IFC_PARSE_API ifcopenshell::impl::in_memory_file_storage* instance_data::get_storage_of_type<ifcopenshell::impl::in_memory_file_storage>() const;
|
||||
template IFC_PARSE_API ifcopenshell::impl::rocks_db_file_storage* instance_data::get_storage_of_type<ifcopenshell::impl::rocks_db_file_storage>() const;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user