Fix Windows (MSVC) and WASM (Emscripten) build failures

Both surfaced on the first Windows/WASM CI run of this branch:

- XmlSerializer.cpp: the IfcPropertySetDefinitionSet block used a C-style
  cast to convert the set to std::vector<IfcPropertySetDefinition>. GCC
  invokes the non-explicit conversion operator; MSVC rejects the cast to a
  template type (C2440/C3536/C2661). Use copy-initialisation instead, which
  invokes the same implicit conversion portably. (This block was dead until
  the SCHEMAS_->SCHEMA_HAS_ typo fix enabled it, so it had never hit MSVC.)

- parse.cpp: the floating-point parse path falls back to strtod_l because
  libc++ =deletes the float from_chars overload. That fallback was guarded
  for __APPLE__ only; Emscripten uses the same libc++, so WASM hit the
  deleted from_chars. Extend the guard to __EMSCRIPTEN__ (its musl provides
  strtod_l/newlocale, treating all locales as C).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-07-26 19:37:11 +10:00
parent c9c3beb139
commit f0c0312e8d
2 changed files with 8 additions and 4 deletions
+3 -3
View File
@@ -134,7 +134,7 @@ std::string& spf_lexer<Reader>::get_temp_string() const {
namespace {
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
double parse_double_c(const char* start, char** end) {
static const locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
return strtod_l(start, end, loc);
@@ -154,11 +154,11 @@ bool parse_num_(const char* pStart, size_t size, T& val) {
}
}
if constexpr (std::is_floating_point_v<T>) {
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
// pStart is NUL-terminated at pStart + size (callers pass c_str()), so
// strtod_l stops exactly at the end of a well-formed number. from_chars
// is not instantiated for double here — its float overload is =deleted
// in Apple's libc++.
// in libc++ (Apple's and Emscripten's).
char* pEnd = nullptr;
const double result = parse_double_c(pStart, &pEnd);
if (pEnd != pStart + size) {
@@ -300,7 +300,11 @@ ptree* descend(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping,
(log, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
for (auto& s : property_set_sets) {
auto set_sets_value = (decltype(property_sets))s;
// Copy-initialise (not a C-style cast) so the implicit
// IfcPropertySetDefinitionSet -> std::vector<IfcPropertySetDefinition>
// conversion operator is used. MSVC rejects the equivalent cast to a
// template type (C2440), whereas copy-initialisation is portable.
decltype(property_sets) set_sets_value = s;
property_sets.insert(property_sets.end(), set_sets_value.begin(), set_sets_value.end());
}
#endif