| 90 | |
| 91 | template <size_t Depth, typename Fn> |
| 92 | void construct_(boost::optional<size_t> instance_id, int attribute_id, IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Fn fn) { |
| 93 | if (p.tokens_.empty()) { |
| 94 | // @todo instead of ugly if-else we could also default initialize the respective |
| 95 | // variant types below. |
| 96 | if (aggr) { |
| 97 | auto aggr_type = IfcUtil::make_aggregate(IfcUtil::from_parameter_type(aggr->type_of_element())); |
| 98 | if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_INT) { |
| 99 | fn(std::vector<int>{}); |
| 100 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) { |
| 101 | fn(std::vector<double>{}); |
| 102 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_STRING) { |
| 103 | fn(std::vector<std::string>{}); |
| 104 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_BINARY) { |
| 105 | fn(std::vector<boost::dynamic_bitset<>>{}); |
| 106 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) { |
| 107 | fn(aggregate_of_instance::ptr(new aggregate_of_instance)); |
| 108 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) { |
| 109 | fn(std::vector<std::vector<int>>{}); |
| 110 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) { |
| 111 | fn(std::vector<std::vector<double>>{}); |
| 112 | } else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) { |
| 113 | fn(aggregate_of_aggregate_of_instance::ptr(new aggregate_of_aggregate_of_instance)); |
| 114 | } |
| 115 | } |
| 116 | return; |
| 117 | } |
| 118 | |
| 119 | typedef std::variant< |
| 120 | Blank, |
| 121 | |
| 122 | std::vector<int>, |
| 123 | std::vector<double>, |
| 124 | std::vector<std::string>, |
| 125 | std::vector<boost::dynamic_bitset<>>, |
| 126 | std::vector<IfcParse::reference_or_simple_type>, |
| 127 | |
| 128 | std::vector<std::vector<int>>, |
| 129 | std::vector<std::vector<double>>, |
| 130 | std::vector<std::vector<IfcParse::reference_or_simple_type>> |
| 131 | > possible_aggregation_types_t; |
| 132 | |
| 133 | possible_aggregation_types_t aggregate_storage; |
| 134 | |
| 135 | auto append_to_aggregate_storage = [&aggregate_storage](const auto& v) { |
| 136 | if constexpr (is_type_in_variant_v<possible_aggregation_types_t, std::vector<std::decay_t<decltype(v)>>>) { |
| 137 | if (aggregate_storage.index() == 0) { |
| 138 | aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v }; |
| 139 | } else { |
| 140 | if (auto* vec_ptr = std::get_if<std::vector<std::decay_t<decltype(v)>>>(&aggregate_storage)) { |
| 141 | vec_ptr->push_back(v); |
| 142 | } else { |
| 143 | if constexpr (std::is_same_v<std::decay_t<decltype(v)>, int>) { |
| 144 | auto* vec_ptr2 = std::get_if<std::vector<double>>(&aggregate_storage); |
| 145 | if (vec_ptr2) { |
| 146 | // double[] + int |
| 147 | vec_ptr2->push_back((double) v); |
| 148 | } |
| 149 | } |