mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
Don't eat opening parens on nested list
This commit is contained in:
@@ -41,86 +41,6 @@ namespace {
|
||||
template<typename Variant, typename T>
|
||||
constexpr bool is_type_in_variant_v = is_type_in_variant<Variant, T>::value;
|
||||
|
||||
|
||||
IfcUtil::ArgumentType get_element_type(IfcUtil::ArgumentType aggregate) {
|
||||
switch (aggregate) {
|
||||
case IfcUtil::Argument_AGGREGATE_OF_INT:
|
||||
return IfcUtil::Argument_INT;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE:
|
||||
return IfcUtil::Argument_DOUBLE;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_STRING:
|
||||
return IfcUtil::Argument_STRING;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_BINARY:
|
||||
return IfcUtil::Argument_BINARY;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE:
|
||||
return IfcUtil::Argument_ENTITY_INSTANCE;
|
||||
|
||||
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE:
|
||||
return IfcUtil::Argument_EMPTY_AGGREGATE;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT:
|
||||
return IfcUtil::Argument_AGGREGATE_OF_INT;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE:
|
||||
return IfcUtil::Argument_AGGREGATE_OF_DOUBLE;
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE:
|
||||
return IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE;
|
||||
|
||||
default:
|
||||
return IfcUtil::Argument_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
bool can_coerce(IfcUtil::ArgumentType target, IfcUtil::ArgumentType source) {
|
||||
if (source == IfcUtil::Argument_EMPTY_AGGREGATE) {
|
||||
return target == IfcUtil::Argument_AGGREGATE_OF_INT ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_DOUBLE ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_STRING ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_BINARY ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
|
||||
} if (source == IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE) {
|
||||
return target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE ||
|
||||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
|
||||
} else if (source == IfcUtil::Argument_BOOL && target == IfcUtil::Argument_LOGICAL) {
|
||||
return true;
|
||||
} else {
|
||||
// @todo make it configurable to coerce int to double, which is not standard compliant?
|
||||
auto elt = get_element_type(target);
|
||||
auto els = get_element_type(source);
|
||||
if (elt != IfcUtil::Argument_UNKNOWN && els != IfcUtil::Argument_UNKNOWN) {
|
||||
return can_coerce(elt, els);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// we need to have a compatibility between (#123, IfcLengthMeasure(123.))
|
||||
// which are different token kinds
|
||||
void get_token_type(std::vector<uint8_t>& r, const boost::variant<IfcUtil::IfcBaseClass*,IfcParse::Token, IfcParse::parse_context*>& v) {
|
||||
r.push_back((uint8_t)v.which());
|
||||
if (v.which() == 0) {
|
||||
// pass
|
||||
} else if (v.which() == 1) {
|
||||
r.push_back((uint8_t)boost::get<IfcParse::Token>(v).type);
|
||||
} else if (v.which() == 2) {
|
||||
// @todo check for empty aggregate
|
||||
get_token_type(r, boost::get<IfcParse::parse_context*>(v)->tokens_.front());
|
||||
}
|
||||
}
|
||||
|
||||
bool can_coerce(const std::vector<uint8_t>& target, const std::vector<uint8_t>& source) {
|
||||
if (target == std::vector<uint8_t>{0, 0} && source == std::vector<uint8_t>{1, IfcParse::Token_IDENTIFIER}) {
|
||||
return true;
|
||||
}
|
||||
if (source == std::vector<uint8_t>{0, 0} && target == std::vector<uint8_t>{1, IfcParse::Token_IDENTIFIER}) {
|
||||
return true;
|
||||
}
|
||||
return source == target;
|
||||
}
|
||||
|
||||
struct InstanceReference {
|
||||
int v;
|
||||
operator int() const {
|
||||
@@ -149,7 +69,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
template <size_t Depth, typename Fn>
|
||||
void construct_(IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Fn fn) {
|
||||
if (p.tokens_.empty()) {
|
||||
// @todo instead of ugly if-else we could also default initialize the respective
|
||||
@@ -203,6 +123,7 @@ namespace {
|
||||
vec_ptr->push_back(v);
|
||||
} else {
|
||||
// inconsistent aggregate valuation
|
||||
// @todo boolean -> logical upgrade
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -216,14 +137,10 @@ namespace {
|
||||
// @todo get aggregate of enumeration
|
||||
dispatch_token(v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, append_to_aggregate_storage);
|
||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
|
||||
/*construct_(*v, [&aggregate_storage](auto& v) {
|
||||
if (aggregate_storage.which() == 0) {
|
||||
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
|
||||
} else {
|
||||
boost::get<std::vector<std::decay_t<decltype(v)>>>(aggregate_storage).push_back(v);
|
||||
}
|
||||
});*/
|
||||
// Too deeply nested list
|
||||
if constexpr (Depth < 3) {
|
||||
construct_<Depth + 1>(*v, nullptr, append_to_aggregate_storage);
|
||||
}
|
||||
// nested list
|
||||
} else {
|
||||
append_to_aggregate_storage(v);
|
||||
}
|
||||
@@ -294,11 +211,11 @@ IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_re
|
||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
|
||||
const auto *pt = param_type;
|
||||
if (pt) {
|
||||
while (pt->as_named_type()) {
|
||||
while (pt->as_named_type() && pt->as_named_type()->declared_type()->as_type_declaration()) {
|
||||
pt = pt->as_named_type()->declared_type()->as_type_declaration()->declared_type();
|
||||
}
|
||||
}
|
||||
construct_(*v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const auto& v) {
|
||||
construct_<0>(*v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const auto& v) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
|
||||
references_to_resolve.push_back({ {name, index }, v });
|
||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<std::vector<reference_or_simple_type>>>) {
|
||||
|
||||
@@ -689,9 +689,11 @@ std::string TokenFunc::toString(const Token& token) {
|
||||
void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::entity* entity, parse_context& context, int attribute_index) {
|
||||
Token next = tokens->Next();
|
||||
|
||||
/*
|
||||
if (TokenFunc::isOperator(next, '(')) {
|
||||
next = tokens->Next();
|
||||
}
|
||||
*/
|
||||
|
||||
size_t attribute_index_within_data = 0;
|
||||
size_t return_value = 0;
|
||||
@@ -715,6 +717,7 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
|
||||
if (TokenFunc::isKeyword(next)) {
|
||||
try {
|
||||
parse_context ps;
|
||||
tokens->Next();
|
||||
load(0, nullptr, ps, -1);
|
||||
const auto *decl = schema_->declaration_by_name(TokenFunc::asStringRef(next));
|
||||
auto* simple_type_instance = schema_->instantiate(decl, ps.construct(-1, references_to_resolve, decl));
|
||||
@@ -744,6 +747,7 @@ IfcEntityInstanceData IfcParse::read(unsigned int i, IfcFile* f) {
|
||||
}
|
||||
const IfcParse::declaration* ty = f->schema()->declaration_by_name(TokenFunc::asStringRef(datatype));
|
||||
parse_context pc;
|
||||
f->tokens->Next();
|
||||
f->load(i, ty->as_entity(), pc, -1);
|
||||
return IfcEntityInstanceData(pc.construct(i, f->references_to_resolve, ty));
|
||||
}
|
||||
@@ -1295,6 +1299,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
|
||||
}
|
||||
|
||||
parse_context ps;
|
||||
tokens->Next();
|
||||
load(current_id, entity_type->as_entity(), ps, -1);
|
||||
instance = schema_->instantiate(entity_type, ps.construct(current_id, references_to_resolve, entity_type));
|
||||
instance->file_ = this;
|
||||
|
||||
@@ -39,6 +39,7 @@ using namespace IfcParse;
|
||||
namespace {
|
||||
IfcEntityInstanceData read_from_file(IfcFile* f, size_t s) {
|
||||
parse_context pc;
|
||||
f->tokens->Next();
|
||||
f->load(-1, nullptr, pc, -1);
|
||||
return pc.construct(-1, f->references_to_resolve, nullptr);
|
||||
/*std::ostringstream oss;
|
||||
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
// in various places.
|
||||
throw IfcParse::IfcException(
|
||||
"Type held at index " + std::to_string(index) + " is " +
|
||||
get_type_name(index) + " and not " + typeid(T).name()
|
||||
get_type_name(size_and_indices_[index + 1]) + " and not " + typeid(T).name()
|
||||
);
|
||||
}
|
||||
using V = typename std::tuple_element<impl::TypeIndex_v<T, Types...>, impl::MapTypes_t<Types... >>::type;
|
||||
|
||||
Reference in New Issue
Block a user