ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
materialepas_traits.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#pragma once
6
8#include <array>
9#include <cstddef>
10
11namespace reusex::core::traits {
12
22 const char *field_name;
23
25 const char *leksikon_guid;
26
30 const char *json_name;
31
34
36 size_t offset;
37
40
42 size_t nested_count = 0;
43};
44
55template <typename T> struct PropertyTraits {
60 static constexpr const PropertyDescriptor *properties() noexcept;
61
66 static constexpr size_t property_count() noexcept;
67
72 static constexpr const char *struct_name() noexcept;
73};
74
75// ============================================================================
76// Helper Functions for Creating PropertyDescriptors
77// ============================================================================
78
79namespace detail {
80
95template <typename T>
96constexpr PropertyDescriptor
97make_property(const char *field_name, const char *leksikon_guid,
98 const char *json_name, PropertyType type,
99 size_t field_offset) noexcept {
100 return PropertyDescriptor{field_name, leksikon_guid, json_name, type,
101 field_offset, nullptr, 0};
102}
103
118template <typename T, typename NestedT>
119constexpr PropertyDescriptor
120make_nested_property(const char *field_name, const char *json_name,
121 size_t field_offset) noexcept {
122 return PropertyDescriptor{field_name,
123 "", // No GUID for nested arrays
124 json_name,
126 field_offset,
129}
130
131} // namespace detail
132
133} // namespace reusex::core::traits
134
135// ===========================================================================
136// Include types before specializations
137// ===========================================================================
138
139#include "materialepas_types.hpp"
140
141namespace reusex::core::traits {
142
143// Bring types into scope for convenience
153using ::reusex::core::Owner;
156
157// ===========================================================================
158// Template Specializations
159// ===========================================================================
160
161// ===========================================================================
162// Section 1: Owner (3 properties)
163// ===========================================================================
164
165template <> struct PropertyTraits<Owner> {
166 static inline constexpr std::array properties_array = {
167 detail::make_property<Owner>("contact_email", "0Bwj05D$55V931bq9VaBE5",
168 "materialpassport owner contact email",
170 offsetof(Owner, contact_email)),
171 detail::make_property<Owner>("contact_name", "17BdeQk152gR5YUt5oSLfp",
172 "materialpassport owner contact name",
174 offsetof(Owner, contact_name)),
175 detail::make_property<Owner>("company_name", "1bb51PIefCe9uHGCmR0gFJ",
176 "materialpassport owner company name",
178 offsetof(Owner, company_name))};
179
180 static constexpr const PropertyDescriptor *properties() noexcept {
181 return properties_array.data();
182 }
183
184 static constexpr size_t property_count() noexcept {
185 return properties_array.size();
186 }
187
188 static constexpr const char *struct_name() noexcept { return "Owner"; }
189};
190
191// ===========================================================================
192// Section 2: Construction Item Description (8 properties)
193// ===========================================================================
194
196 static inline constexpr std::array properties_array = {
198 "designation", "2_mYRkA$9EcwXAxqBGoMrM",
199 "construction item designation", PropertyType::String,
200 offsetof(ConstructionItemDescription, designation)),
202 "images", "1dvQfmc2z9lB_rwknYkM3y", "construction item image",
204 offsetof(ConstructionItemDescription, images)),
206 "has_qr_code", "06moAxe0j7EutROb0dD3B7", "has QR code",
208 offsetof(ConstructionItemDescription, has_qr_code)),
210 "has_rfid_tag", "2$Owq1iHrAuw$ASWOXAk9p", "has RFID tag",
212 offsetof(ConstructionItemDescription, has_rfid_tag)),
214 "materials", "1R_z75Gd52OQYxVkJ$E3ZU", "material",
216 offsetof(ConstructionItemDescription, materials)),
218 "assembly_methods", "0N7Qwopp125xrULezqArw4", "assembly method",
220 offsetof(ConstructionItemDescription, assembly_methods)),
222 "year_of_installation", "294ZkUyYn6TfdwCsbo2X63",
223 "year of installation", PropertyType::Integer,
224 offsetof(ConstructionItemDescription, year_of_installation)),
226 "year_of_construction", "17LFECVML6buNXwBLz416Y",
227 "year of construction of the building", PropertyType::Integer,
228 offsetof(ConstructionItemDescription, year_of_construction))};
229
230 static constexpr const PropertyDescriptor *properties() noexcept {
231 return properties_array.data();
232 }
233
234 static constexpr size_t property_count() noexcept {
235 return properties_array.size();
236 }
237
238 static constexpr const char *struct_name() noexcept {
239 return "ConstructionItemDescription";
240 }
241};
242
243// ===========================================================================
244// Section 3: Product Information (5 properties)
245// ===========================================================================
246
248 static inline constexpr std::array properties_array = {
250 "manufacturer", "1QwFy1F3T4dPe2N2cbsuRv", "manufacturer",
251 PropertyType::String, offsetof(ProductInformation, manufacturer)),
253 "gtin", "1rQ9Z5vy5AygUSncyWuhXr", "global trade item number (GTIN)",
256 "product_name", "198tMTFIX5PecEfAwMEIeo", "product name",
257 PropertyType::String, offsetof(ProductInformation, product_name)),
259 "model_label", "06t2gkj49FNvMebmltrHXV", "model label",
260 PropertyType::String, offsetof(ProductInformation, model_label)),
262 "production_year", "3nif2XJKH8r9I09LfEYaRm", "production year",
264 offsetof(ProductInformation, production_year))};
265
266 static constexpr const PropertyDescriptor *properties() noexcept {
267 return properties_array.data();
268 }
269
270 static constexpr size_t property_count() noexcept {
271 return properties_array.size();
272 }
273
274 static constexpr const char *struct_name() noexcept {
275 return "ProductInformation";
276 }
277};
278
279// ===========================================================================
280// Section 4: Certifications (13 properties)
281// ===========================================================================
282
283template <> struct PropertyTraits<Certifications> {
284 static inline constexpr std::array properties_array = {
286 "has_epd", "2_jn1$mEr1780H5QOiEj6O",
287 "environmental product declaration (EPD)", PropertyType::Boolean,
288 offsetof(Certifications, has_epd)),
290 "epd_programme_operator", "0ORiYBKRnCFQzUwOsNqbYn",
291 "EPD programme operator", PropertyType::String,
292 offsetof(Certifications, epd_programme_operator)),
294 "epd_operator_web_domain", "2kqTixLBr9sBqGKYs9lNSI",
295 "EPD programme operator web domain", PropertyType::String,
296 offsetof(Certifications, epd_operator_web_domain)),
298 "epd_registration_number", "2aCraAVB91qw8CzrM6x3ia",
299 "EPD registration number", PropertyType::String,
300 offsetof(Certifications, epd_registration_number)),
302 "reference_service_life", "28mSsPe_z69BksBt5oRXMl",
303 "reference service life", PropertyType::Double,
304 offsetof(Certifications, reference_service_life)),
306 "has_safety_data_sheet", "3D1KFVwbDBuumnIBZZHQId",
307 "has safety data sheet", PropertyType::Boolean,
308 offsetof(Certifications, has_safety_data_sheet)),
310 "declaration_of_performance", "1tqCmrJwn3yvF$k2lU2fFa",
311 "declaration of performance", PropertyType::StringArray,
312 offsetof(Certifications, declaration_of_performance)),
314 "technical_documentation", "1IfrbnqGv5Pu3GBuocLZgi",
315 "technical documentation", PropertyType::StringArray,
316 offsetof(Certifications, technical_documentation)),
318 "non_destructive_tests", "0aTBceworF$QTXM6CqyOdV",
319 "non-destructive tests", PropertyType::StringArray,
320 offsetof(Certifications, non_destructive_tests)),
322 "assessed_period_of_use", "3xW23JRMTAzOQb79uZW3qC",
323 "assessed period of use", PropertyType::Double,
324 offsetof(Certifications, assessed_period_of_use)),
326 "avg_service_life_build", "2TtVRWo_56mBphAcSiFIHG",
327 "average service life (BUILD)", PropertyType::Double,
328 offsetof(Certifications, avg_service_life_build)),
330 "remaining_service_life_rsl", "2id4UZ8ynAF9DEzV0NC_wT",
331 "service life (RSL)", PropertyType::Double,
332 offsetof(Certifications, remaining_service_life_rsl)),
334 "remaining_service_life_build", "27gXAA5Iz7lgcOytMRqOBv",
335 "remaining service life (BUILD)", PropertyType::Double,
336 offsetof(Certifications, remaining_service_life_build))};
337
338 static constexpr const PropertyDescriptor *properties() noexcept {
339 return properties_array.data();
340 }
341
342 static constexpr size_t property_count() noexcept {
343 return properties_array.size();
344 }
345
346 static constexpr const char *struct_name() noexcept {
347 return "Certifications";
348 }
349};
350
351// ===========================================================================
352// Section 5: Dimensions (11 properties)
353// ===========================================================================
354
355template <> struct PropertyTraits<Dimensions> {
356 static inline constexpr std::array properties_array = {
357 detail::make_property<Dimensions>("width_mm", "3NHBUedX9438Hi3mwD15$Z",
358 "width", PropertyType::Double,
359 offsetof(Dimensions, width_mm)),
360 detail::make_property<Dimensions>("height_mm", "2G$wMhUvL2LgKNY0J66oAT",
361 "height", PropertyType::Double,
362 offsetof(Dimensions, height_mm)),
363 detail::make_property<Dimensions>("length_mm", "1uUn3YWZfBaPqYQMo_$Om$",
364 "length", PropertyType::Double,
365 offsetof(Dimensions, length_mm)),
367 "thickness_mm", "0SyXPZ9an9vh49k$Lgkvly", "thickness",
368 PropertyType::Double, offsetof(Dimensions, thickness_mm)),
369 detail::make_property<Dimensions>("depth_mm", "1$OV5du3LFWwa$P7SfJhAr",
370 "depth", PropertyType::Double,
371 offsetof(Dimensions, depth_mm)),
372 detail::make_property<Dimensions>("volume_m3", "3IHRMkfs9EDPXVvPJ0hbFn",
373 "volume", PropertyType::Double,
374 offsetof(Dimensions, volume_m3)),
376 "surface_area_m2", "3Cs4d96Ff1nPGHWlsTyYIS",
377 "surface area of product", PropertyType::Double,
378 offsetof(Dimensions, surface_area_m2)),
380 "inner_diameter_mm", "0ayREcz2zBuPWmCDTem2a8", "inner diameter",
381 PropertyType::Double, offsetof(Dimensions, inner_diameter_mm)),
383 "outer_diameter_mm", "3BWwvo0lf3iAd_34y7ac$4", "outer diameter",
384 PropertyType::Double, offsetof(Dimensions, outer_diameter_mm)),
385 detail::make_property<Dimensions>("weight_kg", "1XyLvnxf94pwJW6LWaD6Zw",
386 "weight", PropertyType::Double,
387 offsetof(Dimensions, weight_kg)),
389 "technical_drawing", "2d01jZqvP7GOR3V$coAprV", "technical drawing",
390 PropertyType::String, offsetof(Dimensions, technical_drawing))};
391
392 static constexpr const PropertyDescriptor *properties() noexcept {
393 return properties_array.data();
394 }
395
396 static constexpr size_t property_count() noexcept {
397 return properties_array.size();
398 }
399
400 static constexpr const char *struct_name() noexcept { return "Dimensions"; }
401};
402
403// ===========================================================================
404// Section 6: Condition (8 properties)
405// ===========================================================================
406
407template <> struct PropertyTraits<Condition> {
408 static inline constexpr std::array properties_array = {
410 "photo_documentation", "3$DH1Zm_r9_gzqdwKK39Ua",
411 "photo documentation", PropertyType::StringArray,
412 offsetof(Condition, photo_documentation)),
414 "visual_inspection_performed", "2jB20LC_nEzBN4_j2ypip8",
415 "visual inspection performed", PropertyType::Boolean,
416 offsetof(Condition, visual_inspection_performed)),
418 "has_signs_of_damage", "0rQimGJFHEueqtqwbwBaC5",
419 "has signs of damage", PropertyType::Boolean,
420 offsetof(Condition, has_signs_of_damage)),
421 detail::make_property<Condition>("is_deformed", "1g6mt3SrvDlho6YqBIu1lW",
422 "is deformed", PropertyType::Boolean,
423 offsetof(Condition, is_deformed)),
424 detail::make_property<Condition>("is_scratched", "365luGupDCfwgtD32gGGrS",
425 "is scratched", PropertyType::Boolean,
426 offsetof(Condition, is_scratched)),
428 "is_surface_intact", "2GO932BuX5EvXOecmhbbl3", "is surface intact",
429 PropertyType::Boolean, offsetof(Condition, is_surface_intact)),
431 "has_intact_edges", "0AoBmqQ9v1pw7ca1VVp_Za", "has intact edges",
432 PropertyType::Boolean, offsetof(Condition, has_intact_edges)),
434 "has_signs_of_degradation", "01lVHQF$XAneE8CFtajgr_",
435 "has signs of degradation", PropertyType::Boolean,
436 offsetof(Condition, has_signs_of_degradation))};
437
438 static constexpr const PropertyDescriptor *properties() noexcept {
439 return properties_array.data();
440 }
441
442 static constexpr size_t property_count() noexcept {
443 return properties_array.size();
444 }
445
446 static constexpr const char *struct_name() noexcept { return "Condition"; }
447};
448
449// ===========================================================================
450// Section 7: Pollution - Nested Types (DangerousSubstance, Emission)
451// ===========================================================================
452
453// DangerousSubstance (5 properties - nested)
455 static inline constexpr std::array properties_array = {
457 "content_method", "2ympiI4PL6c8ooh9Agqnz4",
458 "content of dangerous substances", PropertyType::EnumValue,
459 offsetof(DangerousSubstance, content_method)),
461 "analyzed_substance", "3Y2oTiV9r3NfoZQBVP_Bpx",
462 "analyzed for chemical substances", PropertyType::String,
463 offsetof(DangerousSubstance, analyzed_substance)),
465 "cas_number", "2tZYDby2H2PADWYcTMn50O", "CAS-number",
466 PropertyType::String, offsetof(DangerousSubstance, cas_number)),
468 "ec_number", "1cV5alHQ93Zu44Uv4Iuqoj", "EC-number",
469 PropertyType::String, offsetof(DangerousSubstance, ec_number)),
471 "concentration_mg_per_kg", "0yw_0Ggsf6ihdShOA1niRl",
472 "concentration of substance", PropertyType::Double,
473 offsetof(DangerousSubstance, concentration_mg_per_kg))};
474
475 static constexpr const PropertyDescriptor *properties() noexcept {
476 return properties_array.data();
477 }
478
479 static constexpr size_t property_count() noexcept {
480 return properties_array.size();
481 }
482
483 static constexpr const char *struct_name() noexcept {
484 return "DangerousSubstance";
485 }
486};
487
488// Emission (7 properties - nested)
489template <> struct PropertyTraits<Emission> {
490 static inline constexpr std::array properties_array = {
491 detail::make_property<Emission>("standard", "1Kx6G$uIXEZO3Br$MEsdaB",
492 "emission standard", PropertyType::String,
493 offsetof(Emission, standard)),
494 detail::make_property<Emission>("type", "12ZQ3obYHB1OhXiyy3LcfK",
495 "emission type", PropertyType::String,
496 offsetof(Emission, type)),
498 "lower_interval", "1dSnTNTGD5YQPcgcbzMJaD", "emission lower Interval",
499 PropertyType::Double, offsetof(Emission, lower_interval)),
501 "upper_interval", "3YTotdivHEeQS4ij2Xa7PU", "emission upper Interval",
502 PropertyType::Double, offsetof(Emission, upper_interval)),
504 "quantity_type", "33HQrsPDn9uhOu$7D3HhWU", "emission quantity type",
505 PropertyType::EnumValue, offsetof(Emission, quantity_type)),
507 "measuring_unit", "3d1HQUJVb23ReixUzvSyvS", "measuring unit",
508 PropertyType::String, offsetof(Emission, measuring_unit)),
509 detail::make_property<Emission>("quantity", "0lZ6gflK18WBte7dMyQQ$h", "",
511 offsetof(Emission, quantity))};
512
513 static constexpr const PropertyDescriptor *properties() noexcept {
514 return properties_array.data();
515 }
516
517 static constexpr size_t property_count() noexcept {
518 return properties_array.size();
519 }
520
521 static constexpr const char *struct_name() noexcept { return "Emission"; }
522};
523
524// Pollution (9 properties including 2 nested arrays)
525template <> struct PropertyTraits<Pollution> {
526 static inline constexpr std::array properties_array = {
528 "contains_reach_substances", "2E6_MQ4Cn36f0s6CVYxQOR",
529 "contains substances on REACH's candidate list",
531 offsetof(Pollution, contains_reach_substances)),
533 "is_chemically_treated", "1Cf0jFllr2HAk8FOmT2VGr",
534 "is construction item chemically treated", PropertyType::TriState,
535 offsetof(Pollution, is_chemically_treated)),
537 "surface_treatments", "1zV5ZyYKT6CPWjKdTEZ1K0", "surface treatment",
538 PropertyType::StringArray, offsetof(Pollution, surface_treatments)),
540 "dangerous_substances", "dangerous substances",
541 offsetof(Pollution, dangerous_substances)),
543 "emissions", "release of dangerous substances",
544 offsetof(Pollution, emissions)),
546 "intended_for_indoor_use", "2W1zl8TFb459xOVytRmX3J",
547 "intended for indoor use", PropertyType::Boolean,
548 offsetof(Pollution, intended_for_indoor_use)),
550 "labelling_scheme", "3Txv$QA7zCp8azbWeuubx2", "labelling scheme",
551 PropertyType::String, offsetof(Pollution, labelling_scheme)),
553 "emission_level", "3areU4Rpv9gfbeDNE9eBgA", "emission level",
554 PropertyType::String, offsetof(Pollution, emission_level)),
556 "has_asbestos_analysis", "2962p$Lwj68Br6satSNLAn",
557 "has asbestos analysis", PropertyType::Boolean,
558 offsetof(Pollution, has_asbestos_analysis))};
559
560 static constexpr const PropertyDescriptor *properties() noexcept {
561 return properties_array.data();
562 }
563
564 static constexpr size_t property_count() noexcept {
565 return properties_array.size();
566 }
567
568 static constexpr const char *struct_name() noexcept { return "Pollution"; }
569};
570
571// ===========================================================================
572// Section 8: Environmental Potential (2 properties)
573// ===========================================================================
574
576 static inline constexpr std::array properties_array = {
578 "takeback_scheme_available", "2__I$nkL94YRI_YCBy0ou8",
579 "take-back scheme available", PropertyType::Boolean,
580 offsetof(EnvironmentalPotential, takeback_scheme_available)),
582 "consists_of_separate_parts", "2nZqcaXkz7YPHhKI$FMowg",
583 "construction item consists of separate parts naturally ",
585 offsetof(EnvironmentalPotential, consists_of_separate_parts))};
586
587 static constexpr const PropertyDescriptor *properties() noexcept {
588 return properties_array.data();
589 }
590
591 static constexpr size_t property_count() noexcept {
592 return properties_array.size();
593 }
594
595 static constexpr const char *struct_name() noexcept {
596 return "EnvironmentalPotential";
597 }
598};
599
600// ===========================================================================
601// Section 9: Fire Properties (4 properties)
602// ===========================================================================
603
604template <> struct PropertyTraits<FireProperties> {
605 static inline constexpr std::array properties_array = {
607 "reaction_to_fire", "2bipZ4JrzDnwNZZHkwfk8O", "reaction to fire",
608 PropertyType::String, offsetof(FireProperties, reaction_to_fire)),
610 "resistance_to_fire", "0NlhENUQr4YA5$p0zBrXSp", "resistance to fire",
611 PropertyType::String, offsetof(FireProperties, resistance_to_fire)),
613 "documentation_of_fire_classification", "1DdkDjj1H7POQtnzDtu7CC",
614 "documentation of fire classification", PropertyType::String,
615 offsetof(FireProperties, documentation_of_fire_classification)),
617 "field_of_application", "37sNiQNwHC399AW2B60MrY",
618 "field of application in relation to fire", PropertyType::String,
619 offsetof(FireProperties, field_of_application))};
620
621 static constexpr const PropertyDescriptor *properties() noexcept {
622 return properties_array.data();
623 }
624
625 static constexpr size_t property_count() noexcept {
626 return properties_array.size();
627 }
628
629 static constexpr const char *struct_name() noexcept {
630 return "FireProperties";
631 }
632};
633
634// ===========================================================================
635// Section 10: History (1 property)
636// ===========================================================================
637
638template <> struct PropertyTraits<History> {
639 static inline constexpr std::array properties_array = {
641 "previous_usage_environments", "3BiwSSLEz9l8YLgoWcixHq",
642 "previous usage environment", PropertyType::StringArray,
643 offsetof(History, previous_usage_environments))};
644
645 static constexpr const PropertyDescriptor *properties() noexcept {
646 return properties_array.data();
647 }
648
649 static constexpr size_t property_count() noexcept {
650 return properties_array.size();
651 }
652
653 static constexpr const char *struct_name() noexcept { return "History"; }
654};
655
656} // namespace reusex::core::traits
constexpr PropertyDescriptor make_nested_property(const char *field_name, const char *json_name, size_t field_offset) noexcept
Create a nested object array property descriptor.
constexpr PropertyDescriptor make_property(const char *field_name, const char *leksikon_guid, const char *json_name, PropertyType type, size_t field_offset) noexcept
Create a simple property descriptor (non-nested).
PropertyType
Property type enumeration for MaterialPassport serialization.
@ TriState
TriState enum (yes/no/unknown).
@ ObjectArray
std::vector<StructType> (nested objects)
Certifications, approvals and declarations for the item.
Condition assessment of the construction item.
Description of the reused construction item.
Dangerous substance analysis record.
Physical dimensions and geometry of the construction item.
Emission measurement record.
Environmental and resource potential for sustainable utilization.
Fire-related properties of the construction item.
Historical usage information for the construction item.
Owner contact information for the material passport.
Pollution, content and emission information.
Original product information.
size_t nested_count
For nested types: number of properties in nested array.
const PropertyDescriptor * nested_properties
For nested types (ObjectArray): pointer to nested property array.
const char * field_name
C++ field name (e.g., "contact_email").
size_t offset
Offset of field in struct (calculated via offsetof macro).
const char * leksikon_guid
Molio leksiCon GUID (e.g., "0Bwj05D$55V931bq9VaBE5").
const char * json_name
JSON export name matching the Danish standard template (e.g., "materialpassport owner contact email")...
static constexpr const char * struct_name() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const char * struct_name() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const char * struct_name() noexcept
static constexpr const char * struct_name() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const char * struct_name() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr size_t property_count() noexcept
static constexpr const char * struct_name() noexcept
static constexpr const char * struct_name() noexcept
static constexpr size_t property_count() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const char * struct_name() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
static constexpr const PropertyDescriptor * properties() noexcept
Trait interface for property metadata.
static constexpr const char * struct_name() noexcept
Get human-readable struct name.
static constexpr const PropertyDescriptor * properties() noexcept
Get array of property descriptors.
static constexpr size_t property_count() noexcept
Get number of properties in the struct.