| 1087 | |
| 1088 | template <typename T> |
| 1089 | typename std::enable_if< |
| 1090 | (!(std::is_pointer<T>::value&& std::is_base_of<IfcUtil::IfcBaseClass, typename std::remove_pointer<T>::type>::value) || std::is_same_v<IfcUtil::IfcBaseClass, std::remove_pointer_t<T>>), |
| 1091 | void>::type |
| 1092 | IfcUtil::IfcBaseClass::set_attribute_value(size_t i, const T& t) { |
| 1093 | if constexpr (std::is_same_v<std::decay_t<T>, double>) { |
| 1094 | if (!std::isfinite(t)) { |
| 1095 | throw IfcParse::IfcException("Only finite values are allowed"); |
| 1096 | } |
| 1097 | } |
| 1098 | if constexpr (std::is_same_v<std::decay_t<T>, std::vector<double>>) { |
| 1099 | if (std::any_of(t.begin(), t.end(), [](double d) { return !std::isfinite(d); })) { |
| 1100 | throw IfcParse::IfcException("Only finite values are allowed"); |
| 1101 | } |
| 1102 | } |
| 1103 | if constexpr (std::is_same_v<std::decay_t<T>, std::vector<std::vector<double>>>) { |
| 1104 | for (auto& tt : t) { |
| 1105 | if (std::any_of(tt.begin(), tt.end(), [](double d) { return !std::isfinite(d); })) { |
| 1106 | throw IfcParse::IfcException("Only finite values are allowed"); |
| 1107 | } |
| 1108 | } |
| 1109 | } |
| 1110 | auto current_attribute = get_attribute_value(i); |
| 1111 | if (file_ != nullptr) { |
| 1112 | |
| 1113 | // Deregister old attribute guid in file guid map. |
| 1114 | if (i == 0 && (file_->ifcroot_type() != nullptr) && this->declaration().is(*file_->ifcroot_type())) { |
| 1115 | try { |
| 1116 | auto guid = (std::string) current_attribute; |
| 1117 | auto it = file_->internal_guid_map().find(guid); |
| 1118 | if (it != file_->internal_guid_map().end()) { |
| 1119 | const std::pair<const std::string, IfcUtil::IfcBaseClass*>& p = *it; |
| 1120 | if (p.second == this) { |
| 1121 | file_->internal_guid_map().erase(it); |
| 1122 | } |
| 1123 | } |
| 1124 | } catch (IfcParse::IfcException& e) { |
| 1125 | Logger::Error(e); |
| 1126 | } |
| 1127 | } |
| 1128 | |
| 1129 | if constexpr (std::is_same_v<T, IfcUtil::IfcBaseClass*> || std::is_same_v<T, aggregate_of_instance::ptr> || std::is_same_v<T, aggregate_of_aggregate_of_instance::ptr> || std::is_same_v<T, Blank>) { |
| 1130 | // Deregister inverse indices in file |
| 1131 | unregister_inverse_visitor visitor(*file_, this); |
| 1132 | apply_individual_instance_visitor(current_attribute, (int)i).apply(visitor); |
| 1133 | } |
| 1134 | } |
| 1135 | { |
| 1136 | void* const storage = file_ ? std::visit([](const auto& m) { return (void*)&m; }, file_->storage_) : nullptr; |
| 1137 | if constexpr (std::is_pointer_v<T>) { |
| 1138 | if (t) { |
| 1139 | data_.set_attribute_value(storage, &declaration(), id() ? id() : identity(), i, t); |
| 1140 | } else { |
| 1141 | data_.set_attribute_value(storage, &declaration(), id() ? id() : identity(), i, Blank{}); |
| 1142 | } |
| 1143 | } else { |
| 1144 | data_.set_attribute_value(storage, &declaration(), id() ? id() : identity(),i, t); |
| 1145 | } |
| 1146 | } |
no test coverage detected