From 4345c7479bf40b83b02a6af63605ee80b335c774 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 09:26:52 +0100 Subject: [PATCH 01/30] Support readonly required-member constructors --- Tests/DanceX11/readonly_api.cpp | 9 +++ XSC/be/CXX/Elements.cpp | 110 ++++++++++++++++++++++++++++++++ XSC/be/CXX/Elements.hpp | 6 ++ XSC/be/CXX/Generator.cpp | 3 + XSC/be/CXX/Header.cpp | 21 +++++- XSC/be/CXX/Inline.cpp | 33 +++++----- 6 files changed, 165 insertions(+), 17 deletions(-) diff --git a/Tests/DanceX11/readonly_api.cpp b/Tests/DanceX11/readonly_api.cpp index 50edc9c..8bf8e2f 100644 --- a/Tests/DanceX11/readonly_api.cpp +++ b/Tests/DanceX11/readonly_api.cpp @@ -1,4 +1,5 @@ #include "toplevel.readonly.hpp" +#include "Basic_Deployment_Data.readonly.hpp" #include #include @@ -7,12 +8,20 @@ namespace { using TopLevel = Deployment::TopLevelPackageDescription; + using DataValue = Deployment::DataValue; + using DataType = Deployment::DataType; + using Any = Deployment::Any; using Package = Deployment::PackageConfiguration; using Packages = TopLevel::package_container_type; using LocalityKind = Deployment::PlanLocalityKind; using PlanLocality = Deployment::PlanLocality; static_assert (std::is_same_v>); + static_assert (std::is_default_constructible_v); + static_assert (std::is_copy_constructible_v); + static_assert (!std::is_move_constructible_v); + static_assert (std::is_copy_constructible_v); + static_assert (std::is_constructible_v); static_assert (!std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); static_assert (std::is_same_v ().begin ()), diff --git a/XSC/be/CXX/Elements.cpp b/XSC/be/CXX/Elements.cpp index e460f3a..9046edb 100644 --- a/XSC/be/CXX/Elements.cpp +++ b/XSC/be/CXX/Elements.cpp @@ -6,6 +6,7 @@ #include "XSC/Traversal.hpp" #include +#include #include // Namespace @@ -436,6 +437,115 @@ enumerator_name (SemanticGraph::Enumerator& e) return name; } +void +analyze_read_only_copies (SemanticGraph::Schema& schema) +{ + std::set visited; + std::set copy_types; + + std::function visit_type; + std::function visit_scope; + + visit_scope = [&] (SemanticGraph::Scope& scope) + { + for (auto i (scope.names_begin ()), end (scope.names_end ()); i != end; ++i) + { + SemanticGraph::Names& edge (**i); + SemanticGraph::Nameable& named (edge.named ()); + + if (SemanticGraph::Namespace* ns = + dynamic_cast (std::addressof (named))) + visit_scope (*ns); + else if (SemanticGraph::Type* type = + dynamic_cast (std::addressof (named))) + visit_type (*type); + else if (SemanticGraph::Instance* instance = + dynamic_cast (std::addressof (named))) + visit_type (instance->type ()); + } + }; + + visit_type = [&] (SemanticGraph::Type& type) + { + SemanticGraph::Complex* complex ( + dynamic_cast (std::addressof (type))); + if (complex == nullptr || !visited.insert (complex).second) + return; + + visit_scope (*complex); + + for (auto i (complex->inherits_begin ()), end (complex->inherits_end ()); i != end; ++i) + visit_type ((**i).inheritee ()); + }; + + visit_scope (schema); + + std::function require_copy; + require_copy = [&] (SemanticGraph::Type& type) + { + if (!copy_types.insert (std::addressof (type)).second) + return; + + SemanticGraph::Complex* complex ( + dynamic_cast (std::addressof (type))); + if (complex == nullptr) + return; + + for (auto i (complex->inherits_begin ()), end (complex->inherits_end ()); i != end; ++i) + require_copy ((**i).inheritee ()); + + for (auto i (complex->names_begin ()), end (complex->names_end ()); i != end; ++i) + { + SemanticGraph::Names& edge (**i); + SemanticGraph::Instance* instance ( + dynamic_cast (std::addressof (edge.named ()))); + if (instance != nullptr) + require_copy (instance->type ()); + } + }; + + std::function required_arguments; + required_arguments = [&] (SemanticGraph::Complex& complex) + { + for (auto i (complex.inherits_begin ()), end (complex.inherits_end ()); i != end; ++i) + if (SemanticGraph::Complex* base = + dynamic_cast (std::addressof ((**i).inheritee ()))) + required_arguments (*base); + + for (auto i (complex.names_begin ()), end (complex.names_end ()); i != end; ++i) + { + SemanticGraph::Names& edge (**i); + SemanticGraph::Nameable& named (edge.named ()); + + if (SemanticGraph::Element* element = + dynamic_cast (std::addressof (named))) + { + if (element->min () >= 1) + require_copy (element->type ()); + } + else if (SemanticGraph::Attribute* attribute = + dynamic_cast (std::addressof (named))) + { + if (!attribute->optional ()) + require_copy (attribute->type ()); + } + } + }; + + for (SemanticGraph::Complex* complex : visited) + if (has_constructor_required_members (*complex)) + required_arguments (*complex); + + for (SemanticGraph::Type* type : copy_types) + type->context ().set ("readonly_copy", true); +} + +bool +has_read_only_copy (SemanticGraph::Type& type) +{ + return type.context ().count ("readonly_copy") != 0; +} + string Context:: type_name (SemanticGraph::Instance& i, string const& nss) { diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index afeb524..31e9e4a 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -388,6 +388,12 @@ class Context bool read_only_; }; +void +analyze_read_only_copies (SemanticGraph::Schema& schema); + +bool +has_read_only_copy (SemanticGraph::Type& type); + struct Anonymous : Traversal::Element, Traversal::Complex, protected virtual Context diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index 878b380..e42bf1c 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -69,6 +69,9 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con if (options.count ("cxx-read-only") && cppmode_ != ::Context::CPPMODE::CPP17) throw std::invalid_argument ("--cxx-read-only requires C++17 mode"); + if (options.count ("cxx-read-only")) + analyze_read_only_copies (schema); + //Stores file suffixes (defaults are .hpp, ipp, and cpp) std::string hxx_suffix (options.value ("cxx-header-suffix")); std::string ixx_suffix (options.value ("cxx-inline-suffix")); diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index e4ba475..ad4582d 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -613,11 +613,13 @@ namespace os << Indentation::unindent << "private:" << std::endl << Indentation::indent << name << " ();" << Indentation::unindent << "public:" << std::endl << Indentation::indent; - else + else if (has_constructor_required_members (c)) os << name << " () = delete;"; + else + os << name << " () = default;"; } - if (!this->read_only_) + if (!this->read_only_ || has_constructor_required_members (c)) { os << name << " ("; @@ -676,6 +678,14 @@ namespace if (this->cppmode_ == CPPMODE::CPP03) os << Indentation::unindent << "private:" << std::endl << Indentation::indent << name << " (" << name << " const&);"; + else if (has_read_only_copy (c)) + { + bool const default_copy (this->cppmode_ == CPPMODE::CPP17 && + !has_copy_required_members (c)); + os << name << " (" << name << " const& s)" + << (default_copy ? " = default;" : ";"); + os << name << " (" << name << "&&) = delete;"; + } else { os << name << " (" << name << " const&) = delete;"; @@ -870,6 +880,13 @@ namespace os << Indentation::unindent << "private:" << std::endl << Indentation::indent << name << " (" << name << " const&);" << name << "& operator= (" << name << " const&);"; + else if (has_read_only_copy (e)) + { + os << name << " (" << name << " const&) = default;"; + os << name << " (" << name << "&&) = delete;"; + os << name << "& operator= (" << name << " const&) = delete;"; + os << name << "& operator= (" << name << "&&) = delete;"; + } else { os << name << " (" << name << " const&) = delete;"; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 4a37706..9f487c1 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -574,7 +574,7 @@ namespace bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && !has_constructor_required_members (c)); - if (!this->read_only_ && !default_constructor) + if (!default_constructor) { // c-tor // @@ -605,7 +605,7 @@ namespace bool const default_copy (this->cppmode_ == CPPMODE::CPP17 && !has_copy_required_members (c)); - if (!this->read_only_ && !default_copy) + if ((!this->read_only_ || has_read_only_copy (c)) && !default_copy) { // copy c-tor // @@ -643,22 +643,25 @@ namespace selfcheck = L"if (&s != this)"; } - // operator= - // - os << i - << scope << "& " << scope << "::operator= (" << type << " const& s)" - << "{" - << selfcheck - << "{"; + if (!this->read_only_) + { + // operator= + // + os << i + << scope << "& " << scope << "::operator= (" << type << " const& s)" + << "{" + << selfcheck + << "{"; - inherits (c, assign_base_); - names (c, assign_member_); + inherits (c, assign_base_); + names (c, assign_member_); - os << "}" - << "return *this;" - << "}"; + os << "}" + << "return *this;" + << "}"; - os << std::endl; + os << std::endl; + } } } From cdddcce8ac83904e246079438ce5ec0fc0076d2b Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 09:44:12 +0100 Subject: [PATCH 02/30] Allow copies in readonly generated types --- Tests/DanceX11/readonly_api.cpp | 2 +- Tests/ReadOnly/readonly_api.cpp | 2 +- XSC/be/CXX/Elements.cpp | 110 -------------------------------- XSC/be/CXX/Elements.hpp | 6 -- XSC/be/CXX/Generator.cpp | 3 - XSC/be/CXX/Header.cpp | 16 +---- XSC/be/CXX/Inline.cpp | 2 +- 7 files changed, 5 insertions(+), 136 deletions(-) diff --git a/Tests/DanceX11/readonly_api.cpp b/Tests/DanceX11/readonly_api.cpp index 8bf8e2f..a3faffb 100644 --- a/Tests/DanceX11/readonly_api.cpp +++ b/Tests/DanceX11/readonly_api.cpp @@ -22,7 +22,7 @@ namespace static_assert (!std::is_move_constructible_v); static_assert (std::is_copy_constructible_v); static_assert (std::is_constructible_v); - static_assert (!std::is_copy_constructible_v); + static_assert (std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); static_assert (std::is_same_v ().begin ()), Package const&>); diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index b4c3693..dbde0e1 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -54,7 +54,7 @@ namespace using ReadOnly = ReadOnlyType; static_assert (!std::is_default_constructible_v); - static_assert (!std::is_copy_constructible_v); + static_assert (std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); static_assert (!std::is_copy_assignable_v); static_assert (!std::is_move_assignable_v); diff --git a/XSC/be/CXX/Elements.cpp b/XSC/be/CXX/Elements.cpp index 9046edb..e460f3a 100644 --- a/XSC/be/CXX/Elements.cpp +++ b/XSC/be/CXX/Elements.cpp @@ -6,7 +6,6 @@ #include "XSC/Traversal.hpp" #include -#include #include // Namespace @@ -437,115 +436,6 @@ enumerator_name (SemanticGraph::Enumerator& e) return name; } -void -analyze_read_only_copies (SemanticGraph::Schema& schema) -{ - std::set visited; - std::set copy_types; - - std::function visit_type; - std::function visit_scope; - - visit_scope = [&] (SemanticGraph::Scope& scope) - { - for (auto i (scope.names_begin ()), end (scope.names_end ()); i != end; ++i) - { - SemanticGraph::Names& edge (**i); - SemanticGraph::Nameable& named (edge.named ()); - - if (SemanticGraph::Namespace* ns = - dynamic_cast (std::addressof (named))) - visit_scope (*ns); - else if (SemanticGraph::Type* type = - dynamic_cast (std::addressof (named))) - visit_type (*type); - else if (SemanticGraph::Instance* instance = - dynamic_cast (std::addressof (named))) - visit_type (instance->type ()); - } - }; - - visit_type = [&] (SemanticGraph::Type& type) - { - SemanticGraph::Complex* complex ( - dynamic_cast (std::addressof (type))); - if (complex == nullptr || !visited.insert (complex).second) - return; - - visit_scope (*complex); - - for (auto i (complex->inherits_begin ()), end (complex->inherits_end ()); i != end; ++i) - visit_type ((**i).inheritee ()); - }; - - visit_scope (schema); - - std::function require_copy; - require_copy = [&] (SemanticGraph::Type& type) - { - if (!copy_types.insert (std::addressof (type)).second) - return; - - SemanticGraph::Complex* complex ( - dynamic_cast (std::addressof (type))); - if (complex == nullptr) - return; - - for (auto i (complex->inherits_begin ()), end (complex->inherits_end ()); i != end; ++i) - require_copy ((**i).inheritee ()); - - for (auto i (complex->names_begin ()), end (complex->names_end ()); i != end; ++i) - { - SemanticGraph::Names& edge (**i); - SemanticGraph::Instance* instance ( - dynamic_cast (std::addressof (edge.named ()))); - if (instance != nullptr) - require_copy (instance->type ()); - } - }; - - std::function required_arguments; - required_arguments = [&] (SemanticGraph::Complex& complex) - { - for (auto i (complex.inherits_begin ()), end (complex.inherits_end ()); i != end; ++i) - if (SemanticGraph::Complex* base = - dynamic_cast (std::addressof ((**i).inheritee ()))) - required_arguments (*base); - - for (auto i (complex.names_begin ()), end (complex.names_end ()); i != end; ++i) - { - SemanticGraph::Names& edge (**i); - SemanticGraph::Nameable& named (edge.named ()); - - if (SemanticGraph::Element* element = - dynamic_cast (std::addressof (named))) - { - if (element->min () >= 1) - require_copy (element->type ()); - } - else if (SemanticGraph::Attribute* attribute = - dynamic_cast (std::addressof (named))) - { - if (!attribute->optional ()) - require_copy (attribute->type ()); - } - } - }; - - for (SemanticGraph::Complex* complex : visited) - if (has_constructor_required_members (*complex)) - required_arguments (*complex); - - for (SemanticGraph::Type* type : copy_types) - type->context ().set ("readonly_copy", true); -} - -bool -has_read_only_copy (SemanticGraph::Type& type) -{ - return type.context ().count ("readonly_copy") != 0; -} - string Context:: type_name (SemanticGraph::Instance& i, string const& nss) { diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 31e9e4a..afeb524 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -388,12 +388,6 @@ class Context bool read_only_; }; -void -analyze_read_only_copies (SemanticGraph::Schema& schema); - -bool -has_read_only_copy (SemanticGraph::Type& type); - struct Anonymous : Traversal::Element, Traversal::Complex, protected virtual Context diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index e42bf1c..878b380 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -69,9 +69,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con if (options.count ("cxx-read-only") && cppmode_ != ::Context::CPPMODE::CPP17) throw std::invalid_argument ("--cxx-read-only requires C++17 mode"); - if (options.count ("cxx-read-only")) - analyze_read_only_copies (schema); - //Stores file suffixes (defaults are .hpp, ipp, and cpp) std::string hxx_suffix (options.value ("cxx-header-suffix")); std::string ixx_suffix (options.value ("cxx-inline-suffix")); diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index ad4582d..c423ad5 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -678,7 +678,7 @@ namespace if (this->cppmode_ == CPPMODE::CPP03) os << Indentation::unindent << "private:" << std::endl << Indentation::indent << name << " (" << name << " const&);"; - else if (has_read_only_copy (c)) + else { bool const default_copy (this->cppmode_ == CPPMODE::CPP17 && !has_copy_required_members (c)); @@ -686,11 +686,6 @@ namespace << (default_copy ? " = default;" : ";"); os << name << " (" << name << "&&) = delete;"; } - else - { - os << name << " (" << name << " const&) = delete;"; - os << name << " (" << name << "&&) = delete;"; - } if (this->cppmode_ == CPPMODE::CPP03) os << Indentation::unindent << "private:" << std::endl << Indentation::indent @@ -880,16 +875,9 @@ namespace os << Indentation::unindent << "private:" << std::endl << Indentation::indent << name << " (" << name << " const&);" << name << "& operator= (" << name << " const&);"; - else if (has_read_only_copy (e)) - { - os << name << " (" << name << " const&) = default;"; - os << name << " (" << name << "&&) = delete;"; - os << name << "& operator= (" << name << " const&) = delete;"; - os << name << "& operator= (" << name << "&&) = delete;"; - } else { - os << name << " (" << name << " const&) = delete;"; + os << name << " (" << name << " const&) = default;"; os << name << " (" << name << "&&) = delete;"; os << name << "& operator= (" << name << " const&) = delete;"; os << name << "& operator= (" << name << "&&) = delete;"; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 9f487c1..2843f85 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -605,7 +605,7 @@ namespace bool const default_copy (this->cppmode_ == CPPMODE::CPP17 && !has_copy_required_members (c)); - if ((!this->read_only_ || has_read_only_copy (c)) && !default_copy) + if (!default_copy) { // copy c-tor // From 4f88fb1e753e8cee2d2a6ea5df8138a068b3d1b1 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 13:59:25 +0100 Subject: [PATCH 03/30] Add optional C++17 constructor arguments --- Tests/DanceX11/optional_copy.cpp | 11 ++++ XSC/be/CXX/Elements.hpp | 42 +++++++++++++ XSC/be/CXX/Header.cpp | 102 +++++++++++++++++++++++++++++-- XSC/be/CXX/Inline.cpp | 85 +++++++++++++++++++++----- 4 files changed, 222 insertions(+), 18 deletions(-) diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp index 523a2c8..72e1771 100644 --- a/Tests/DanceX11/optional_copy.cpp +++ b/Tests/DanceX11/optional_copy.cpp @@ -16,5 +16,16 @@ main () Deployment::IdRef source; destination = source; + XMLSchema::IDREF idref ("urn:idref"); + Deployment::IdRef constructed (std::nullopt, idref); + if (constructed.idref_if_set () == nullptr) + return 1; + + Deployment::DataValue::short_container_type shorts; + shorts.emplace_back (1); + Deployment::DataValue sequence_constructed (shorts); + if (sequence_constructed._cxx_short ().size () != 1) + return 1; + return destination.href_if_set () != nullptr; } diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index afeb524..7f23361 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -603,6 +603,48 @@ has_constructor_required_members (SemanticGraph::Complex& c) return t.required; } +struct ConstructorOptionalMembers : Traversal::Element, + Traversal::Attribute +{ + void + traverse (SemanticGraph::Element& e) override + { + if (e.min () == 0) + optional = true; + } + + void + traverse (SemanticGraph::Attribute& a) override + { + if (a.optional ()) + optional = true; + } + + bool optional {}; +}; + +inline bool +has_constructor_optional_members (SemanticGraph::Complex& c) +{ + ConstructorOptionalMembers t; + + std::function visit = [&] (SemanticGraph::Complex& current) + { + for (auto i (current.inherits_begin ()); i != current.inherits_end (); ++i) + if (auto base = dynamic_cast (std::addressof ((**i).inheritee ()))) + visit (*base); + + Traversal::Complex complex; + Traversal::Names names; + complex.edge_traverser (names); + names.node_traverser (t); + complex.traverse (current); + }; + + visit (c); + return t.optional; +} + // Fundamental type mapping helper. // struct Fundamental : Traversal::FundamentalType, diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index c423ad5..25f903f 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -116,6 +116,63 @@ namespace Traversal::Names names_; }; + struct OptionalCtorArgs : Traversal::Complex, + protected Traversal::Element, + protected Traversal::Attribute, + protected virtual Context + { + explicit OptionalCtorArgs (Context& c) + : Context (c) + { + complex_.edge_traverser (inherits_); + complex_.edge_traverser (names_); + inherits_.node_traverser (*this); + names_.node_traverser (*this); + } + + void + traverse (SemanticGraph::Element& e) override + { + if (e.min () == 0) + { + string name (e.name ()); + string argument (id (e.name ())); + if (e.max () == 1) + os << comma () << "::XSCRT::OptionalArg<" << type_name (e) << "> " << argument + << "__ = std::nullopt"; + else + os << comma () << name << "_container_type const& " << argument << "__ = {}"; + } + } + + void + traverse (SemanticGraph::Attribute& a) override + { + if (a.optional ()) + os << comma () << "::XSCRT::OptionalArg<" << type_name (a) << "> " + << id (a.name ()) << "__ = std::nullopt"; + } + + void + traverse_optional (SemanticGraph::Complex& c) + { + first_ = !has_constructor_required_members (c); + complex_.traverse (c); + } + + private: + string + comma () + { + return first_ ? (first_ = false, L"") : L",\n"; + } + + bool first_ {}; + Traversal::Complex complex_; + Traversal::Inherits inherits_; + Traversal::Names names_; + }; + struct Element : Traversal::Element, protected virtual Context { @@ -477,7 +534,8 @@ namespace base_ (c), element_ (c), attribute_ (c), - ctor_args_ (c) + ctor_args_ (c), + optional_ctor_args_ (c) { edge_traverser (inherits_); edge_traverser (names_); @@ -615,18 +673,23 @@ namespace << Indentation::unindent << "public:" << std::endl << Indentation::indent; else if (has_constructor_required_members (c)) os << name << " () = delete;"; - else + else if (this->cppmode_ != CPPMODE::CPP17 || !has_constructor_optional_members (c)) os << name << " () = default;"; } - if (!this->read_only_ || has_constructor_required_members (c)) + bool const has_required (has_constructor_required_members (c)); + bool const has_optional (this->cppmode_ == CPPMODE::CPP17 && has_constructor_optional_members (c)); + + if (!this->read_only_ || has_required || has_optional) { os << name << " ("; ctor_args_.traverse (c); + if (has_optional) + optional_ctor_args_.traverse_optional (c); bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && - !has_constructor_required_members (c)); + !has_required && !has_optional); os << ")" << (default_constructor ? " = default;" : ";") << std::endl; } @@ -759,6 +822,7 @@ namespace Attribute attribute_; CtorArgs ctor_args_; + OptionalCtorArgs optional_ctor_args_; }; struct Enumerator : Traversal::Enumerator, protected virtual Context @@ -1053,6 +1117,36 @@ generate_header (Context& ctx, { ctx.os << "#include " << std::endl; ctx.os << "#include " << std::endl; + if (ctx.cppmode () == Context::CPPMODE::CPP17) + { + ctx.os << "#include " << std::endl + << "#ifndef XSCRT_OPTIONAL_ARG_HPP" << std::endl + << "#define XSCRT_OPTIONAL_ARG_HPP" << std::endl + << "namespace XSCRT" << std::endl + << "{" + << "template " << std::endl + << "class OptionalArg" << std::endl + << "{" << Indentation::unindent << "public:" << std::endl << Indentation::indent + << "OptionalArg (std::nullopt_t) noexcept : value_ (nullptr)" << std::endl + << "{" + << "}" + << "OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl + << "{" + << "}" + << "explicit operator bool () const noexcept" << std::endl + << "{" + << "return value_ != nullptr;" << std::endl + << "}" + << "T const& operator* () const noexcept" << std::endl + << "{" + << "return *value_;" << std::endl + << "}" + << Indentation::unindent << "private:" << std::endl << Indentation::indent + << "T const* value_ {};" << std::endl + << "};" + << "}" + << "#endif // XSCRT_OPTIONAL_ARG_HPP" << std::endl; + } if (ctx.generate_ra_sequences ()) ctx.os << "#include " << std::endl; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 2843f85..24785ae 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -458,7 +458,8 @@ namespace void traverse (SemanticGraph::Enumeration& e) override { - os << comma () << type_name (e) << " const& b__"; + if (!optional_arguments_) + os << comma () << type_name (e) << " const& b__"; } void @@ -467,11 +468,18 @@ namespace string type (type_name (e)); string name (e.name ()); - if (e.min () == 1 && e.max () == 1) + if (optional_arguments_ && e.min () == 0) + { + if (e.max () == 1) + os << comma () << "::XSCRT::OptionalArg<" << type << "> " << id (name) << "__"; + else + os << comma () << name << "_container_type const& " << id (name) << "__"; + } + else if (!optional_arguments_ && e.min () == 1 && e.max () == 1) { os << comma () << type << " const& " << id (name) << "__"; } - else if (e.min () >= 1) + else if (!optional_arguments_ && e.min () >= 1) { os << comma () << name << "_container_type const& " @@ -482,9 +490,13 @@ namespace void traverse (SemanticGraph::Attribute& a) override { - if (!a.optional ()) + if ((!optional_arguments_ && !a.optional ()) || (optional_arguments_ && a.optional ())) { - os << comma () << type_name (a) << " const& " << id (a.name ()) << "__"; + if (optional_arguments_) + os << comma () << "::XSCRT::OptionalArg<" << type_name (a) << "> " << id (a.name ()) + << "__"; + else + os << comma () << type_name (a) << " const& " << id (a.name ()) << "__"; } } @@ -492,7 +504,14 @@ namespace traverse (SemanticGraph::Complex& c) override { first_ = true; + optional_arguments_ = false; complex_.traverse (c); + if (this->cppmode_ == CPPMODE::CPP17 && has_constructor_optional_members (c)) + { + optional_arguments_ = true; + complex_.traverse (c); + } + optional_arguments_ = false; } private: @@ -503,6 +522,7 @@ namespace } bool first_; + bool optional_arguments_ {}; private: Traversal::Complex complex_; @@ -571,8 +591,10 @@ namespace string type (name); bool const has_base (c.inherits_begin () != c.inherits_end ()); + bool const has_required (has_constructor_required_members (c)); + bool const has_optional (this->cppmode_ == CPPMODE::CPP17 && has_constructor_optional_members (c)); bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && - !has_constructor_required_members (c)); + !has_required && !has_optional); if (!default_constructor) { @@ -775,23 +797,29 @@ namespace void traverse (SemanticGraph::Type&) override { - os << comma () << "b__"; + if (!optional_arguments_) + os << comma () << "b__"; } void traverse (SemanticGraph::Enumeration&) override { - os << comma () << "b__"; + if (!optional_arguments_) + os << comma () << "b__"; } void traverse (SemanticGraph::Element& e) override { - if (e.min () == 1 && e.max () == 1) + if (optional_arguments_ && e.min () == 0) + { + os << comma () << id (e.name ()) << "__"; + } + else if (!optional_arguments_ && e.min () == 1 && e.max () == 1) { os << comma () << id (e.name ()) << "__"; } - else if (e.min () >= 1) + else if (!optional_arguments_ && e.min () >= 1) { os << comma () << id (e.name ()) << "__"; } @@ -800,7 +828,7 @@ namespace void traverse (SemanticGraph::Attribute& a) override { - if (!a.optional ()) + if ((!optional_arguments_ && !a.optional ()) || (optional_arguments_ && a.optional ())) { os << comma () << id (a.name ()) << "__"; } @@ -810,8 +838,14 @@ namespace traverse (SemanticGraph::Complex& c) override { first_ = true; - + optional_arguments_ = false; complex_.traverse (c); + if (this->cppmode_ == CPPMODE::CPP17 && has_constructor_optional_members (c)) + { + optional_arguments_ = true; + complex_.traverse (c); + } + optional_arguments_ = false; } private: @@ -822,6 +856,7 @@ namespace } bool first_; + bool optional_arguments_ {}; private: Traversal::Complex complex_; @@ -847,7 +882,21 @@ namespace { ensure_base_class_initialization (); - if (e.min () == 1 && e.max () == 1) + if (this->cppmode_ == CPPMODE::CPP17 && e.min () == 0 && e.max () == 1) + { + ensure_base_class_initialization (); + string name (id (e.name ())); + string type (type_name (e)); + os << ", " << name << "_ (" << name << "__ ? std::make_unique<" << type + << "> (*" << name << "__) : nullptr)" << std::endl; + } + else if (this->cppmode_ == CPPMODE::CPP17 && e.min () == 0) + { + ensure_base_class_initialization (); + string name (id (e.name ())); + os << ", " << name << "_ (" << name << "__)" << std::endl; + } + else if (e.min () == 1 && e.max () == 1) { // one // @@ -881,7 +930,15 @@ namespace void traverse (SemanticGraph::Attribute& a) override { - if (!a.optional ()) + if (this->cppmode_ == CPPMODE::CPP17 && a.optional ()) + { + ensure_base_class_initialization (); + string name (id (a.name ())); + string type (type_name (a)); + os << ", " << name << "_ (" << name << "__ ? std::make_unique<" << type + << "> (*" << name << "__) : nullptr)" << std::endl; + } + else if (!a.optional ()) { ensure_base_class_initialization (); From b149ad57e909443abb684a08bf215873843ae245 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 15:38:52 +0100 Subject: [PATCH 04/30] Fix optional constructor argument commas --- Tests/ReadOnly/readonly.xsd | 15 +++++++++++++++ Tests/ReadOnly/readonly_api.cpp | 4 ++++ XSC/be/CXX/Header.cpp | 12 +++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Tests/ReadOnly/readonly.xsd b/Tests/ReadOnly/readonly.xsd index a163b82..23ad7c2 100644 --- a/Tests/ReadOnly/readonly.xsd +++ b/Tests/ReadOnly/readonly.xsd @@ -1,5 +1,20 @@ + + + + + + + + + + + + + + + diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index dbde0e1..86e2318 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -52,6 +52,7 @@ namespace }; using ReadOnly = ReadOnlyType; + using KindWithOptionalAttribute = ReadOnlyKindWithOptionalAttribute; static_assert (!std::is_default_constructible_v); static_assert (std::is_copy_constructible_v); @@ -70,4 +71,7 @@ namespace ::XMLSchema::string const*>); static_assert (std::is_same_v ().item ()), ReadOnly::item_container_type const&>); + static_assert (std::is_constructible_v>>); } diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 25f903f..39e218b 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -100,6 +100,12 @@ namespace complex_.traverse (c); } + bool + has_arguments () const + { + return !first_; + } + private: string comma () @@ -154,9 +160,9 @@ namespace } void - traverse_optional (SemanticGraph::Complex& c) + traverse_optional (SemanticGraph::Complex& c, bool has_prior_arguments) { - first_ = !has_constructor_required_members (c); + first_ = !has_prior_arguments; complex_.traverse (c); } @@ -686,7 +692,7 @@ namespace ctor_args_.traverse (c); if (has_optional) - optional_ctor_args_.traverse_optional (c); + optional_ctor_args_.traverse_optional (c, ctor_args_.has_arguments ()); bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && !has_required && !has_optional); From 4e40ee3c55407a1ee538c109daf560563dd4e9bf Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 15:48:07 +0100 Subject: [PATCH 05/30] Fix readonly enum constructor CI regression --- .gitignore | 82 +++++++++++++++++++++++++ Tests/DanceX11/readonly_api.cpp | 18 ++++++ Tests/ReadOnly/enum_constructor.xsd | 17 +++++ Tests/ReadOnly/enum_constructor_api.cpp | 7 +++ Tests/ReadOnly/readonly.mpc | 23 +++++++ Tests/ReadOnly/readonly.xsd | 15 ----- Tests/ReadOnly/readonly_api.cpp | 4 -- 7 files changed, 147 insertions(+), 19 deletions(-) create mode 100644 Tests/ReadOnly/enum_constructor.xsd create mode 100644 Tests/ReadOnly/enum_constructor_api.cpp diff --git a/.gitignore b/.gitignore index 445c521..f2c20e9 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,85 @@ Release/ # Generated example output kept local. /Examples/Recursive/recursive.cpp /Examples/Recursive/recursive.hpp +/Tests/ReadOnly/readonly.cpp +/Tests/ReadOnly/readonly.hpp +/Examples/Reference/reference.cpp +/Examples/Reference/reference.hpp +/Tests/Abstract/abstract.cpp +/Tests/Abstract/abstract.hpp +/Tests/Anonymous/test.cpp +/Tests/Anonymous/test.hpp +/Tests/Chameleon/includer.cpp +/Tests/Chameleon/includer.hpp +/Tests/DanceX11/Basic_Deployment_Data.cpp +/Tests/DanceX11/Basic_Deployment_Data.hpp +/Tests/DanceX11/Basic_Deployment_Data.readonly.cpp +/Tests/DanceX11/Basic_Deployment_Data.readonly.hpp +/Tests/DanceX11/Deployment.cpp +/Tests/DanceX11/Deployment.hpp +/Tests/DanceX11/Deployment.readonly.cpp +/Tests/DanceX11/Deployment.readonly.hpp +/Tests/DanceX11/XMI.cpp +/Tests/DanceX11/XMI.hpp +/Tests/DanceX11/XMI.readonly.cpp +/Tests/DanceX11/XMI.readonly.hpp +/Tests/DanceX11/ccd.cpp +/Tests/DanceX11/ccd.hpp +/Tests/DanceX11/ccd.readonly.cpp +/Tests/DanceX11/ccd.readonly.hpp +/Tests/DanceX11/cdd.cpp +/Tests/DanceX11/cdd.hpp +/Tests/DanceX11/cdd.readonly.cpp +/Tests/DanceX11/cdd.readonly.hpp +/Tests/DanceX11/cdp.cpp +/Tests/DanceX11/cdp.hpp +/Tests/DanceX11/cdp.readonly.cpp +/Tests/DanceX11/cdp.readonly.hpp +/Tests/DanceX11/cid.cpp +/Tests/DanceX11/cid.hpp +/Tests/DanceX11/cid.readonly.cpp +/Tests/DanceX11/cid.readonly.hpp +/Tests/DanceX11/cpd.cpp +/Tests/DanceX11/cpd.hpp +/Tests/DanceX11/cpd.readonly.cpp +/Tests/DanceX11/cpd.readonly.hpp +/Tests/DanceX11/iad.cpp +/Tests/DanceX11/iad.hpp +/Tests/DanceX11/iad.readonly.cpp +/Tests/DanceX11/iad.readonly.hpp +/Tests/DanceX11/pcd.cpp +/Tests/DanceX11/pcd.hpp +/Tests/DanceX11/pcd.readonly.cpp +/Tests/DanceX11/pcd.readonly.hpp +/Tests/DanceX11/toplevel.cpp +/Tests/DanceX11/toplevel.hpp +/Tests/DanceX11/toplevel.readonly.cpp +/Tests/DanceX11/toplevel.readonly.hpp +/Tests/DateTime/datetime.cpp +/Tests/DateTime/datetime.hpp +/Tests/Escape/test.cpp +/Tests/Escape/test.hpp +/Tests/Group/test.cpp +/Tests/Group/test.hpp +/Tests/Import/importee.cpp +/Tests/Import/importee.hpp +/Tests/Import/importer.cpp +/Tests/Import/importer.hpp +/Tests/Include/includee.cpp +/Tests/Include/includee.hpp +/Tests/Include/includer.cpp +/Tests/Include/includer.hpp +/Tests/NoNamespace/test.cpp +/Tests/NoNamespace/test.hpp +/Tests/ReadOnly/enum_constructor.cpp +/Tests/ReadOnly/enum_constructor.hpp +/Tests/ReadOnly/readonly.cpp03.cpp +/Tests/ReadOnly/readonly.cpp03.hpp +/Tests/SequenceAccessorCollision/test.cpp +/Tests/SequenceAccessorCollision/test.hpp +/abstract.cpp +/abstract.hpp +/dds_qos.cpp +/dds_qos.hpp +/test.cpp +/test.hpp diff --git a/Tests/DanceX11/readonly_api.cpp b/Tests/DanceX11/readonly_api.cpp index a3faffb..b11b00c 100644 --- a/Tests/DanceX11/readonly_api.cpp +++ b/Tests/DanceX11/readonly_api.cpp @@ -10,7 +10,9 @@ namespace using TopLevel = Deployment::TopLevelPackageDescription; using DataValue = Deployment::DataValue; using DataType = Deployment::DataType; + using TCKind = Deployment::TCKind; using Any = Deployment::Any; + using ExternalReferenceEndpoint = Deployment::ExternalReferenceEndpoint; using Package = Deployment::PackageConfiguration; using Packages = TopLevel::package_container_type; using LocalityKind = Deployment::PlanLocalityKind; @@ -31,4 +33,20 @@ namespace static_assert (std::is_same_v ().constraint () == LocalityKind::SameProcess), bool>); + + [[maybe_unused]] Any make_char_any () + { + TCKind const kind (TCKind::tk_char); + DataType const type (kind); + DataValue const value {}; + return Any (type, value); + } + + [[maybe_unused]] ExternalReferenceEndpoint make_external_reference_endpoint () + { + ::XMLSchema::string const location ("location"); + bool const source_provider (true); + ::XMLSchema::boolean const provider (source_provider); + return ExternalReferenceEndpoint (location, provider); + } } diff --git a/Tests/ReadOnly/enum_constructor.xsd b/Tests/ReadOnly/enum_constructor.xsd new file mode 100644 index 0000000..e9e641a --- /dev/null +++ b/Tests/ReadOnly/enum_constructor.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Tests/ReadOnly/enum_constructor_api.cpp b/Tests/ReadOnly/enum_constructor_api.cpp new file mode 100644 index 0000000..751ecc6 --- /dev/null +++ b/Tests/ReadOnly/enum_constructor_api.cpp @@ -0,0 +1,7 @@ +#include "enum_constructor.hpp" + +#include + +static_assert (std::is_constructible_v>>); diff --git a/Tests/ReadOnly/readonly.mpc b/Tests/ReadOnly/readonly.mpc index 343e7da..fc976db 100644 --- a/Tests/ReadOnly/readonly.mpc +++ b/Tests/ReadOnly/readonly.mpc @@ -24,6 +24,29 @@ project (xsc_test_readonly_generated): xscrt { } } +project (xsc_test_readonly_enum_constructor): xscdefaults { + requires += xsc + custom_only = 1 + xscflags += --cxx-char-type char + xscflags += --cxx-cpp17 + xscflags += --cxx-read-only + + XSC_Files { + enum_constructor.xsd + } + Source_Files { + } +} + +project (xsc_test_readonly_enum_constructor_generated): xscrt { + after += xsc_test_readonly_enum_constructor + + Source_Files { + enum_constructor.cpp + enum_constructor_api.cpp + } +} + project (xsc_test_cpp03_compatibility): xscdefaults { requires += xsc custom_only = 1 diff --git a/Tests/ReadOnly/readonly.xsd b/Tests/ReadOnly/readonly.xsd index 23ad7c2..a163b82 100644 --- a/Tests/ReadOnly/readonly.xsd +++ b/Tests/ReadOnly/readonly.xsd @@ -1,20 +1,5 @@ - - - - - - - - - - - - - - - diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index 86e2318..dbde0e1 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -52,7 +52,6 @@ namespace }; using ReadOnly = ReadOnlyType; - using KindWithOptionalAttribute = ReadOnlyKindWithOptionalAttribute; static_assert (!std::is_default_constructible_v); static_assert (std::is_copy_constructible_v); @@ -71,7 +70,4 @@ namespace ::XMLSchema::string const*>); static_assert (std::is_same_v ().item ()), ReadOnly::item_container_type const&>); - static_assert (std::is_constructible_v>>); } From 3b2624d5e162d43db8aace1f3e5ff5a06b785287 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 15:55:32 +0100 Subject: [PATCH 06/30] Traverse inherited readonly constructor arguments --- Tests/ReadOnly/readonly.xsd | 12 ++++++++++++ Tests/ReadOnly/readonly_api.cpp | 5 +++++ XSC/be/CXX/Header.cpp | 15 +++++++++++++++ XSC/be/CXX/Inline.cpp | 18 ++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/Tests/ReadOnly/readonly.xsd b/Tests/ReadOnly/readonly.xsd index a163b82..d0e9739 100644 --- a/Tests/ReadOnly/readonly.xsd +++ b/Tests/ReadOnly/readonly.xsd @@ -9,4 +9,16 @@ + + + + + + + + + + + + diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index dbde0e1..11aef78 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -52,6 +52,7 @@ namespace }; using ReadOnly = ReadOnlyType; + using Derived = DerivedWithoutMembers; static_assert (!std::is_default_constructible_v); static_assert (std::is_copy_constructible_v); @@ -62,6 +63,10 @@ namespace static_assert (!has_optionalValue_presence_accessor::value); static_assert (!has_item_iterators::value); static_assert (!has_item_count::value); + static_assert (std::is_constructible_v); + static_assert (std::is_constructible_v< + Derived, + ::XSCRT::OptionalArg<::XMLSchema::string>>); static_assert (std::is_same_v>>); static_assert (std::is_same_v ().name ()), diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 39e218b..0732456 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -96,8 +96,16 @@ namespace void traverse (SemanticGraph::Complex& c) override { + if (traversing_) + { + complex_.traverse (c); + return; + } + first_ = true; + traversing_ = true; complex_.traverse (c); + traversing_ = false; } bool @@ -114,6 +122,7 @@ namespace } bool first_; + bool traversing_ {}; private: Traversal::Complex complex_; @@ -159,6 +168,12 @@ namespace << id (a.name ()) << "__ = std::nullopt"; } + void + traverse (SemanticGraph::Complex& c) override + { + complex_.traverse (c); + } + void traverse_optional (SemanticGraph::Complex& c, bool has_prior_arguments) { diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 24785ae..06e63d8 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -503,6 +503,13 @@ namespace void traverse (SemanticGraph::Complex& c) override { + if (traversing_) + { + complex_.traverse (c); + return; + } + + traversing_ = true; first_ = true; optional_arguments_ = false; complex_.traverse (c); @@ -512,6 +519,7 @@ namespace complex_.traverse (c); } optional_arguments_ = false; + traversing_ = false; } private: @@ -523,6 +531,7 @@ namespace bool first_; bool optional_arguments_ {}; + bool traversing_ {}; private: Traversal::Complex complex_; @@ -837,6 +846,13 @@ namespace void traverse (SemanticGraph::Complex& c) override { + if (traversing_) + { + complex_.traverse (c); + return; + } + + traversing_ = true; first_ = true; optional_arguments_ = false; complex_.traverse (c); @@ -846,6 +862,7 @@ namespace complex_.traverse (c); } optional_arguments_ = false; + traversing_ = false; } private: @@ -857,6 +874,7 @@ namespace bool first_; bool optional_arguments_ {}; + bool traversing_ {}; private: Traversal::Complex complex_; From 23b6dba68a5862a8a3744461fa113d0a06fea9e4 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 16:50:59 +0100 Subject: [PATCH 07/30] Make optional argument conversion explicit --- Tests/DanceX11/optional_copy.cpp | 9 ++++++++- XSC/be/CXX/Header.cpp | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp index 72e1771..778d9d4 100644 --- a/Tests/DanceX11/optional_copy.cpp +++ b/Tests/DanceX11/optional_copy.cpp @@ -1,4 +1,10 @@ #include "Basic_Deployment_Data.hpp" +#include + +static_assert (!std::is_convertible_v<::XMLSchema::IDREF, + ::XSCRT::OptionalArg<::XMLSchema::IDREF>>); +static_assert (std::is_constructible_v<::XSCRT::OptionalArg<::XMLSchema::IDREF>, + ::XMLSchema::IDREF const&>); int main () @@ -17,7 +23,8 @@ main () destination = source; XMLSchema::IDREF idref ("urn:idref"); - Deployment::IdRef constructed (std::nullopt, idref); + Deployment::IdRef constructed ( + std::nullopt, ::XSCRT::OptionalArg<::XMLSchema::IDREF> (idref)); if (constructed.idref_if_set () == nullptr) return 1; diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 0732456..f0cbb05 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -1151,7 +1151,7 @@ generate_header (Context& ctx, << "OptionalArg (std::nullopt_t) noexcept : value_ (nullptr)" << std::endl << "{" << "}" - << "OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl + << "explicit OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl << "{" << "}" << "explicit operator bool () const noexcept" << std::endl From 86ddbbe5b33eb914e5f4b21cf051867314d2a40b Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 17:02:41 +0100 Subject: [PATCH 08/30] Test ACE XML utilities through generated code --- .github/workflows/linux.yml | 5 + .gitignore | 4 + Tests/Tests.mwc | 1 + Tests/XMLUtils/generated_types.xsd | 14 +++ Tests/XMLUtils/runtime.cpp | 183 +++++++++++++++++++++++++++++ Tests/XMLUtils/runtime.mpc | 27 +++++ 6 files changed, 234 insertions(+) create mode 100644 Tests/XMLUtils/generated_types.xsd create mode 100644 Tests/XMLUtils/runtime.cpp create mode 100644 Tests/XMLUtils/runtime.mpc diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 68d519f..9ddf103 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -127,6 +127,11 @@ jobs: Pop-Location } shell: pwsh + - name: Run ACE XML_Utils runtime regression + run: | + & "${env:XSC_ROOT}/Tests/XMLUtils/runtime" + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + shell: pwsh - name: Run DanceX11 generated-code test run: | Push-Location ${env:XSC_ROOT}/Tests/DanceX11 diff --git a/.gitignore b/.gitignore index f2c20e9..d6026b2 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,10 @@ Release/ /Tests/ReadOnly/readonly.cpp03.hpp /Tests/SequenceAccessorCollision/test.cpp /Tests/SequenceAccessorCollision/test.hpp +/Tests/XMLUtils/GNUmakefile* +/Tests/XMLUtils/generated_types.cpp +/Tests/XMLUtils/generated_types.hpp +/Tests/XMLUtils/runtime /abstract.cpp /abstract.hpp /dds_qos.cpp diff --git a/Tests/Tests.mwc b/Tests/Tests.mwc index 4a0505e..6dfd722 100644 --- a/Tests/Tests.mwc +++ b/Tests/Tests.mwc @@ -16,4 +16,5 @@ workspace (Tests) { SequenceAccessorCollision UnqualifiedImport Validation + XMLUtils } diff --git a/Tests/XMLUtils/generated_types.xsd b/Tests/XMLUtils/generated_types.xsd new file mode 100644 index 0000000..a638c25 --- /dev/null +++ b/Tests/XMLUtils/generated_types.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp new file mode 100644 index 0000000..80cd727 --- /dev/null +++ b/Tests/XMLUtils/runtime.cpp @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "generated_types.hpp" + +#include +#include +#include +#include +#include +#include + +static_assert (std::is_copy_constructible_v); +static_assert (std::is_copy_assignable_v); + +namespace +{ + struct TypeTraverser : XSCRT::Traversal::Traverser + { + void traverse (XSCRT::Type&) override { ++visits; } + void traverse (XSCRT::Type const&) override { ++visits; } + int visits {}; + }; + + struct StringTraverser : XSCRT::Traversal::Traverser, XSCRT::Type> + { + void traverse (XMLSchema::string&) override { ++visits; } + void traverse (XMLSchema::string const&) override { ++visits; } + int visits {}; + }; + + struct FailingResolver + { + FailingResolver () { throw std::runtime_error ("resolver construction failed"); } + }; +} + +int main () +{ + { + XML::XML_Helper<> helper; + { + XSCRT::XML::string value ("copyable XML string"); + XSCRT::XML::string copy (value); + XSCRT::XML::string assigned (L"temporary"); + assigned = copy; + XSCRT::XML::string moved (std::move (assigned)); + assert (XSCRT::XML::transcode (moved.c_str (), static_cast (nullptr)) == + "copyable XML string"); + } + + XERCES_CPP_NAMESPACE::DOMDocument* const document = + helper.create_dom (ACE_TEXT ("root"), ACE_TEXT ("urn:test")); + assert (document != nullptr); + XERCES_CPP_NAMESPACE::DOMElement* const root (document->getDocumentElement ()); + root->appendChild (document->createTextNode ( + static_cast (XML::XStr ("text")))); + root->appendChild (document->createComment ( + static_cast (XML::XStr ("comment")))); + root->appendChild (document->createElementNS ( + static_cast (XML::XStr ("urn:test")), + static_cast (XML::XStr ("child")))); + + XSCRT::XML::Element root_element (root); + XSCRT::Parser parser (root_element); + assert (parser.more_elements ()); + XSCRT::XML::Element child (parser.next_element ()); + assert (child.name () == "child"); + assert (!parser.more_elements ()); + + XERCES_CPP_NAMESPACE::DOMDocument* const generated_document = + helper.create_dom (ACE_TEXT ("document"), ACE_TEXT ("urn:xsc:xml-utils-test")); + XERCES_CPP_NAMESPACE::DOMElement* const generated_root ( + generated_document->getDocumentElement ()); + XERCES_CPP_NAMESPACE::DOMElement* const label (generated_document->createElementNS ( + static_cast (XML::XStr ("urn:xsc:xml-utils-test")), + static_cast (XML::XStr ("label")))); + label->appendChild (generated_document->createTextNode ( + static_cast (XML::XStr ("sample")))); + generated_root->appendChild (label); + XERCES_CPP_NAMESPACE::DOMElement* const count (generated_document->createElementNS ( + static_cast (XML::XStr ("urn:xsc:xml-utils-test")), + static_cast (XML::XStr ("count")))); + count->appendChild (generated_document->createTextNode ( + static_cast (XML::XStr ("7")))); + generated_root->appendChild (count); + + XMLUtils::documentType const generated_value ( + XMLUtils::reader::document (generated_document)); + assert (generated_value.label () == "sample"); + assert (generated_value.count () == 7); + generated_document->release (); + + bool invalid_numeric_rejected (false); + XERCES_CPP_NAMESPACE::DOMElement* const invalid = + document->createElement (static_cast (XML::XStr ("invalid"))); + invalid->appendChild (document->createTextNode ( + static_cast (XML::XStr ("12junk")))); + try + { + XSCRT::XML::Element element (invalid); + XSCRT::FundamentalType value (element); + } + catch (std::invalid_argument const&) + { + invalid_numeric_rejected = true; + } + assert (invalid_numeric_rejected); + + XSCRT::XML::Element out_of_range (document->createElement ( + static_cast (XML::XStr ("byte")))); + out_of_range.dom_element ()->appendChild ( + document->createTextNode (static_cast (XML::XStr ("200")))); + bool byte_range_rejected (false); + try + { + XSCRT::FundamentalType value (out_of_range); + } + catch (std::out_of_range const&) + { + byte_range_rejected = true; + } + assert (byte_range_rejected); + + assert (helper.write_DOM (document, ACE_TEXT ("xml_utils_runtime_test.xml"))); + assert (!helper.write_DOM (nullptr, ACE_TEXT ("xml_utils_runtime_test.xml"))); + std::remove ("xml_utils_runtime_test.xml"); + document->release (); + + helper.terminate_parser (); + bool uninitialized_rejected (false); + try + { + helper.create_dom (ACE_TEXT ("root"), ACE_TEXT ("urn:test")); + } + catch (std::logic_error const&) + { + uninitialized_rejected = true; + } + assert (uninitialized_rejected); + uninitialized_rejected = false; + try + { + helper.create_dom (ACE_TEXT ("not-a-file.xml")); + } + catch (std::logic_error const&) + { + uninitialized_rejected = true; + } + assert (uninitialized_rejected); + } + + { + bool initialization_error_propagated (false); + try + { + XML::XML_Helper helper; + } + catch (std::runtime_error const&) + { + initialization_error_propagated = true; + } + assert (initialization_error_propagated); + } + + { + XSCRT::ExtendedTypeInfoMap& map (XSCRT::extended_type_info_map ()); + XMLSchema::TypeInfoInitializer initialize (map); + XMLSchema::token token ("valid-token"); + TypeTraverser traverser; + traverser.dispatch (token); + assert (traverser.visits == 1); + + StringTraverser string_traverser; + string_traverser.dispatch (token); + assert (string_traverser.visits == 1); + } +} diff --git a/Tests/XMLUtils/runtime.mpc b/Tests/XMLUtils/runtime.mpc new file mode 100644 index 0000000..2a4c74b --- /dev/null +++ b/Tests/XMLUtils/runtime.mpc @@ -0,0 +1,27 @@ +project (xsc_test_xml_utils_runtime): xscdefaults { + requires += xsc + custom_only = 1 + + xscflags += --cxx-cpp17 + xscflags += --cxx-char-type char + xscflags += --cxx-namespace-regex + xscflags += "/.*xml-utils-test.*/XMLUtils/" + + XSC_Files { + generated_types.xsd + } + + Source_Files { + } +} + +project (xsc_test_xml_utils_runtime_generated): xscrt { + after += xsc_test_xml_utils_runtime + libpaths += $(ACE_ROOT)/lib + libs += ACE_XML_Utils + + Source_Files { + runtime.cpp + generated_types.cpp + } +} From c988387aa10672f6de441521acc074a24de811fc Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 17:09:11 +0100 Subject: [PATCH 09/30] Reject temporary optional arguments and fix base forwarding --- Tests/DanceX11/optional_copy.cpp | 4 ++++ Tests/ReadOnly/readonly.xsd | 16 ++++++++++++++++ Tests/ReadOnly/readonly_api.cpp | 6 ++++++ XSC/be/CXX/Header.cpp | 2 ++ XSC/be/CXX/Inline.cpp | 3 +-- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp index 778d9d4..1389943 100644 --- a/Tests/DanceX11/optional_copy.cpp +++ b/Tests/DanceX11/optional_copy.cpp @@ -5,6 +5,10 @@ static_assert (!std::is_convertible_v<::XMLSchema::IDREF, ::XSCRT::OptionalArg<::XMLSchema::IDREF>>); static_assert (std::is_constructible_v<::XSCRT::OptionalArg<::XMLSchema::IDREF>, ::XMLSchema::IDREF const&>); +static_assert (!std::is_constructible_v<::XSCRT::OptionalArg<::XMLSchema::IDREF>, + ::XMLSchema::IDREF&&>); +static_assert (!std::is_constructible_v<::XSCRT::OptionalArg<::XMLSchema::IDREF>, + ::XMLSchema::IDREF const&&>); int main () diff --git a/Tests/ReadOnly/readonly.xsd b/Tests/ReadOnly/readonly.xsd index d0e9739..737ee17 100644 --- a/Tests/ReadOnly/readonly.xsd +++ b/Tests/ReadOnly/readonly.xsd @@ -21,4 +21,20 @@ + + + + + + + + + + + + + + + + diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index 11aef78..e4b3f79 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -53,6 +53,7 @@ namespace using ReadOnly = ReadOnlyType; using Derived = DerivedWithoutMembers; + using SimpleDerived = SimpleContentDerived; static_assert (!std::is_default_constructible_v); static_assert (std::is_copy_constructible_v); @@ -61,6 +62,11 @@ namespace static_assert (!std::is_move_assignable_v); static_assert (!has_name_setter::value); static_assert (!has_optionalValue_presence_accessor::value); + static_assert (std::is_copy_constructible_v); + static_assert (std::is_constructible_v< + SimpleDerived, + ::XSCRT::OptionalArg<::XMLSchema::string>, + ::XSCRT::OptionalArg<::XMLSchema::string>>); static_assert (!has_item_iterators::value); static_assert (!has_item_count::value); static_assert (std::is_constructible_v); diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index f0cbb05..7c0014e 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -1154,6 +1154,8 @@ generate_header (Context& ctx, << "explicit OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl << "{" << "}" + << "OptionalArg (T&&) = delete;" << std::endl + << "OptionalArg (T const&&) = delete;" << std::endl << "explicit operator bool () const noexcept" << std::endl << "{" << "return value_ != nullptr;" << std::endl diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 06e63d8..102f45c 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -806,8 +806,7 @@ namespace void traverse (SemanticGraph::Type&) override { - if (!optional_arguments_) - os << comma () << "b__"; + // Fundamental simple bases do not declare a b__ constructor argument. } void From 124921e2eff358a496f7eef66b7387f12a7f1b2c Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 17:13:22 +0100 Subject: [PATCH 10/30] Run XSC runtime tests through ACE test runner --- .github/workflows/linux.yml | 38 ++----------------------------------- Tests/README.md | 15 +++++++++++++++ Tests/XMLUtils/run_test.pl | 32 +++++++++++++++++++++++++++++++ Tests/run_test.lst | 6 ++++++ 4 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 Tests/README.md create mode 100644 Tests/XMLUtils/run_test.pl create mode 100644 Tests/run_test.lst diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9ddf103..0904d69 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -94,28 +94,6 @@ jobs: Pop-Location } shell: pwsh - - name: Run XSC validation rejection test - run: | - Push-Location ${env:XSC_ROOT}/Tests/Validation - try { - perl run_test.pl - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - } - finally { - Pop-Location - } - shell: pwsh - - name: Run read-only mode compatibility tests - run: | - Push-Location ${env:XSC_ROOT}/Tests/ReadOnly - try { - perl run_test.pl - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - } - finally { - Pop-Location - } - shell: pwsh - name: Build XSC generated schema tests run: | Push-Location ${env:XSC_ROOT}/Tests @@ -127,19 +105,7 @@ jobs: Pop-Location } shell: pwsh - - name: Run ACE XML_Utils runtime regression - run: | - & "${env:XSC_ROOT}/Tests/XMLUtils/runtime" - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - shell: pwsh - - name: Run DanceX11 generated-code test + - name: Run XSC tests run: | - Push-Location ${env:XSC_ROOT}/Tests/DanceX11 - try { - perl run_test.pl - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - } - finally { - Pop-Location - } + perl ${env:ACE_ROOT}/bin/auto_run_tests.pl -r ${env:XSC_ROOT} -l Tests/run_test.lst shell: pwsh diff --git a/Tests/README.md b/Tests/README.md new file mode 100644 index 0000000..24a9a82 --- /dev/null +++ b/Tests/README.md @@ -0,0 +1,15 @@ +# XSC tests + +The generated-code tests are compiled through `Tests.mwc`. After building XSC +and its ACE dependencies, run the full test suite locally with: + +```sh +source ./setenv.sh +export LD_LIBRARY_PATH="$XSC_ROOT/XSC/utils:$XSC_ROOT/lib:$ACE_ROOT/lib:$LD_LIBRARY_PATH" +perl "$ACE_ROOT/bin/mwc.pl" -type gnuace Tests/Tests.mwc -workers 4 +make -j8 -C Tests +perl "$ACE_ROOT/bin/auto_run_tests.pl" -r "$XSC_ROOT" -l Tests/run_test.lst +``` + +`run_test.lst` lists the runtime test drivers. The other test directories contain +compile-time generated-code and API checks, which run as part of the MPC build. diff --git a/Tests/XMLUtils/run_test.pl b/Tests/XMLUtils/run_test.pl new file mode 100644 index 0000000..30aba3b --- /dev/null +++ b/Tests/XMLUtils/run_test.pl @@ -0,0 +1,32 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +use strict; +use warnings; + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +my $target = PerlACE::TestTarget::create_target (1) + || die "Create target 1 failed\n"; + +my $test = "$ENV{XSC_ROOT}/Tests/XMLUtils/runtime"; +unless (-x $test) { + die "ERROR: Cannot find executable $test\n"; +} + +my $process = $target->CreateProcess ($test); +my $result = $process->SpawnWaitKill ($target->ProcessStartWaitInterval ()); + +if ($result == -1) { + print STDERR "ERROR: ACE XML_Utils runtime regression timed out\n"; + exit 1; +} +elsif ($result != 0) { + print STDERR "ERROR: ACE XML_Utils runtime regression failed with status $result\n"; + exit 1; +} + +print "ACE XML_Utils runtime regression passed\n"; +exit 0; diff --git a/Tests/run_test.lst b/Tests/run_test.lst new file mode 100644 index 0000000..6c244f3 --- /dev/null +++ b/Tests/run_test.lst @@ -0,0 +1,6 @@ +# Runtime test drivers for the XSC test suite. +# Compile-only generated-code and API checks run from Tests.mwc. +Tests/Validation/run_test.pl +Tests/ReadOnly/run_test.pl +Tests/DanceX11/run_test.pl +Tests/XMLUtils/run_test.pl From 4f574333959af0127bce288eafc61a2bcff9cfa7 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 17:15:31 +0100 Subject: [PATCH 11/30] Test rejection of negative unsigned XML values --- Tests/XMLUtils/runtime.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp index 80cd727..86b23ff 100644 --- a/Tests/XMLUtils/runtime.cpp +++ b/Tests/XMLUtils/runtime.cpp @@ -112,6 +112,21 @@ int main () } assert (invalid_numeric_rejected); + XSCRT::XML::Element negative_unsigned (document->createElement ( + static_cast (XML::XStr ("negative-unsigned")))); + negative_unsigned.dom_element ()->appendChild ( + document->createTextNode (static_cast (XML::XStr ("-1")))); + bool negative_unsigned_rejected (false); + try + { + XSCRT::FundamentalType value (negative_unsigned); + } + catch (std::invalid_argument const&) + { + negative_unsigned_rejected = true; + } + assert (negative_unsigned_rejected); + XSCRT::XML::Element out_of_range (document->createElement ( static_cast (XML::XStr ("byte")))); out_of_range.dom_element ()->appendChild ( From 93988b6842838d9fd89c5604e9e632014d603581 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Tue, 27 Oct 2026 18:56:01 +0100 Subject: [PATCH 12/30] Generate a single OptionalArg rvalue rejection overload --- Tests/ReadOnly/readonly_api.cpp | 3 +++ XSC/be/CXX/Header.cpp | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index e4b3f79..bdbc8ea 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -54,7 +54,10 @@ namespace using ReadOnly = ReadOnlyType; using Derived = DerivedWithoutMembers; using SimpleDerived = SimpleContentDerived; + using ConstOptionalArg = ::XSCRT::OptionalArg; + static_assert (std::is_constructible_v); + static_assert (!std::is_constructible_v); static_assert (!std::is_default_constructible_v); static_assert (std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 7c0014e..5b103c0 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -1154,7 +1154,6 @@ generate_header (Context& ctx, << "explicit OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl << "{" << "}" - << "OptionalArg (T&&) = delete;" << std::endl << "OptionalArg (T const&&) = delete;" << std::endl << "explicit operator bool () const noexcept" << std::endl << "{" From c079aef5b6967c4f56f438d6c9e7ad5b1ac49513 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 08:10:43 +0100 Subject: [PATCH 13/30] Fix XMLUtils test workspace setup --- Tests/README.md | 11 ++++++++--- Tests/Tests.mwc | 1 + Tests/XMLUtils/runtime.mpc | 4 +--- XSC.mwc | 1 + 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Tests/README.md b/Tests/README.md index 24a9a82..dd67040 100644 --- a/Tests/README.md +++ b/Tests/README.md @@ -1,10 +1,15 @@ # XSC tests -The generated-code tests are compiled through `Tests.mwc`. After building XSC -and its ACE dependencies, run the full test suite locally with: +The generated-code tests are compiled through `Tests.mwc`. From the XSC repository +root, set the environment variables for your ACE/TAO and MPC checkouts, then run +the full test suite after building XSC and its ACE dependencies: ```sh -source ./setenv.sh +export XSC_ROOT="$(pwd)" +export DOC_ROOT="/path/to/ACE_TAO" +export ACE_ROOT="$DOC_ROOT/ACE" +export TAO_ROOT="$DOC_ROOT/TAO" +export MPC_ROOT="/path/to/MPC" export LD_LIBRARY_PATH="$XSC_ROOT/XSC/utils:$XSC_ROOT/lib:$ACE_ROOT/lib:$LD_LIBRARY_PATH" perl "$ACE_ROOT/bin/mwc.pl" -type gnuace Tests/Tests.mwc -workers 4 make -j8 -C Tests diff --git a/Tests/Tests.mwc b/Tests/Tests.mwc index 6dfd722..d9bbccd 100644 --- a/Tests/Tests.mwc +++ b/Tests/Tests.mwc @@ -1,6 +1,7 @@ workspace (Tests) { cmdline += -include $XSC_ROOT/MPC/config + $(ACE_ROOT)/ace/XML_Utils/XML.mpc Abstract Anonymous Chameleon diff --git a/Tests/XMLUtils/runtime.mpc b/Tests/XMLUtils/runtime.mpc index 2a4c74b..cf4c558 100644 --- a/Tests/XMLUtils/runtime.mpc +++ b/Tests/XMLUtils/runtime.mpc @@ -15,10 +15,8 @@ project (xsc_test_xml_utils_runtime): xscdefaults { } } -project (xsc_test_xml_utils_runtime_generated): xscrt { +project (xsc_test_xml_utils_runtime_generated): xscrt, ace_xml_utils { after += xsc_test_xml_utils_runtime - libpaths += $(ACE_ROOT)/lib - libs += ACE_XML_Utils Source_Files { runtime.cpp diff --git a/XSC.mwc b/XSC.mwc index 148fe64..36d27a8 100644 --- a/XSC.mwc +++ b/XSC.mwc @@ -9,6 +9,7 @@ workspace (XSC) { } $(ACE_ROOT)/ace/ace.mpc + $(ACE_ROOT)/ace/XML_Utils/XML.mpc XSC/utils XSC/XSC.mpc From 8707a10a35efd8f7fade70671ecd3571f402b0cc Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 08:12:07 +0100 Subject: [PATCH 14/30] Validate readonly required XML members --- Tests/DanceX11/dancex11.mpc | 20 ++++++++++ Tests/DanceX11/required_members.cpp | 57 +++++++++++++++++++++++++++++ Tests/DanceX11/run_test.pl | 22 +++++++++++ XSC/be/CXX/Source.cpp | 46 +++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 Tests/DanceX11/required_members.cpp diff --git a/Tests/DanceX11/dancex11.mpc b/Tests/DanceX11/dancex11.mpc index a621558..41050d5 100644 --- a/Tests/DanceX11/dancex11.mpc +++ b/Tests/DanceX11/dancex11.mpc @@ -106,3 +106,23 @@ project (xsc_test_dancex11_optional_copy): xscrt { optional_copy.cpp } } + +project (xsc_test_dancex11_required_members): xscrt { + after += xsc_test_dancex11_readonly + libs += ACE_XML_Utils + + Source_Files { + Basic_Deployment_Data.readonly.cpp + Deployment.readonly.cpp + XMI.readonly.cpp + ccd.readonly.cpp + cdd.readonly.cpp + cdp.readonly.cpp + cid.readonly.cpp + cpd.readonly.cpp + iad.readonly.cpp + pcd.readonly.cpp + toplevel.readonly.cpp + required_members.cpp + } +} diff --git a/Tests/DanceX11/required_members.cpp b/Tests/DanceX11/required_members.cpp new file mode 100644 index 0000000..b996900 --- /dev/null +++ b/Tests/DanceX11/required_members.cpp @@ -0,0 +1,57 @@ +#include "iad.readonly.hpp" + +#include +#include +#include + +#include + +namespace +{ + bool + rejected (bool include_name, bool include_referenced_artifact) + { + XML::XML_Helper<> helper; + XERCES_CPP_NAMESPACE::DOMDocument* const document = helper.create_dom ( + ACE_TEXT ("NamedImplementationArtifact"), + ACE_TEXT ("http://www.omg.org/Deployment")); + XERCES_CPP_NAMESPACE::DOMElement* const root (document->getDocumentElement ()); + + if (include_name) + { + XERCES_CPP_NAMESPACE::DOMElement* const name = document->createElementNS ( + static_cast (XML::XStr ("http://www.omg.org/Deployment")), + static_cast (XML::XStr ("name"))); + name->appendChild (document->createTextNode ( + static_cast (XML::XStr ("artifact")))); + root->appendChild (name); + } + + if (include_referenced_artifact) + { + root->appendChild (document->createElementNS ( + static_cast (XML::XStr ("http://www.omg.org/Deployment")), + static_cast (XML::XStr ("referencedArtifact")))); + } + + bool missing_member_rejected (false); + try + { + XSCRT::XML::Element const element (root); + Deployment::NamedImplementationArtifact value (element); + } + catch (std::invalid_argument const&) + { + missing_member_rejected = true; + } + + document->release (); + return missing_member_rejected; + } +} + +int +main () +{ + return rejected (false, true) && rejected (true, false) ? 0 : 1; +} diff --git a/Tests/DanceX11/run_test.pl b/Tests/DanceX11/run_test.pl index 225fdb8..94616bb 100644 --- a/Tests/DanceX11/run_test.pl +++ b/Tests/DanceX11/run_test.pl @@ -32,4 +32,26 @@ print "DanceX11 generated copy assignment passed\n"; } +my $required_members_test = "$ENV{XSC_ROOT}/Tests/DanceX11/required_members"; +unless (-x $required_members_test) { + die "ERROR: Cannot find executable $required_members_test\n"; +} + +$target->AddLibPath ("$ENV{XSC_ROOT}/Tests/DanceX11"); +my $required_members_process = $target->CreateProcess ($required_members_test); +my $required_members_result = $required_members_process->SpawnWaitKill ( + $target->ProcessStartWaitInterval ()); + +if ($required_members_result == -1) { + print STDERR "ERROR: DanceX11 required-member test could not be started or timed out\n"; + $status = 1; +} +elsif ($required_members_result != 0) { + print STDERR "ERROR: read-only parser accepted a missing required child element\n"; + $status = 1; +} +else { + print "DanceX11 generated required-member checks passed\n"; +} + exit $status; diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 9041f82..1fbf101 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -341,6 +341,45 @@ namespace bool first_; }; + struct RequiredMemberCheck : Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + explicit RequiredMemberCheck (Context& c) + : Context (c) + { + } + + void + traverse (SemanticGraph::Element& e) override + { + if (e.min () == 0) + return; + + string const name (e.name ()); + if (e.max () != 1) + os << "if (" << id (name) << "_.size () < " << e.min () << ")" + << "throw std::invalid_argument (\"missing required XML element: " + << name << "\");"; + else + os << "if (!" << id (name) << "_)" + << "throw std::invalid_argument (\"missing required XML element: " + << name << "\");"; + } + + void + traverse (SemanticGraph::Attribute& a) override + { + if (a.optional ()) + return; + + string const name (a.name ()); + os << "if (!" << id (name) << "_)" + << "throw std::invalid_argument (\"missing required XML attribute: " + << name << "\");"; + } + }; + // Traverser for CDR write operations struct CDR_WriterTraverser : Traversal::Complex, protected Traversal::Type, @@ -1227,12 +1266,14 @@ namespace name (name_), element_ (c), attribute_ (c), + required_member_check_ (c), cdr_writer_ (c), cdr_reader_ (c) { names_elements_.node_traverser (element_); names_attributes_.node_traverser (attribute_); names_anonymous_.node_traverser (anonymous_type); + required_members_.node_traverser (required_member_check_); } @@ -1309,6 +1350,9 @@ namespace os << "}"; // while loop } + + if (this->read_only_) + names (c, required_members_); } } @@ -1394,9 +1438,11 @@ namespace Traversal::Names names_elements_; Traversal::Names names_attributes_; + Traversal::Names required_members_; Element element_; Attribute attribute_; + RequiredMemberCheck required_member_check_; Traversal::Names names_anonymous_; From 99c5ba7b89ae92ae06d3337ad207b9610fc0f081 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 08:16:29 +0100 Subject: [PATCH 15/30] Test negative zero in unsigned XML parsing --- Tests/XMLUtils/runtime.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp index 86b23ff..931d674 100644 --- a/Tests/XMLUtils/runtime.cpp +++ b/Tests/XMLUtils/runtime.cpp @@ -127,6 +127,24 @@ int main () } assert (negative_unsigned_rejected); + XSCRT::XML::Element negative_zero (document->createElement ( + static_cast (XML::XStr ("negative-zero")))); + negative_zero.dom_element ()->appendChild ( + document->createTextNode (static_cast (XML::XStr ("-0")))); + XSCRT::FundamentalType zero (negative_zero); + assert (static_cast (zero) == 0); + + XERCES_CPP_NAMESPACE::DOMElement* const unsigned_attribute_element = + document->createElement (static_cast (XML::XStr ("unsigned-attribute"))); + unsigned_attribute_element->setAttribute ( + static_cast (XML::XStr ("value")), + static_cast (XML::XStr ("-0"))); + XSCRT::XML::Attribute negative_zero_attribute ( + unsigned_attribute_element->getAttributeNode ( + static_cast (XML::XStr ("value")))); + XSCRT::FundamentalType attribute_zero (negative_zero_attribute); + assert (static_cast (attribute_zero) == 0); + XSCRT::XML::Element out_of_range (document->createElement ( static_cast (XML::XStr ("byte")))); out_of_range.dom_element ()->appendChild ( From 3da8b390d4e808d1154a3f7216efb92be4579bca Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 09:34:52 +0100 Subject: [PATCH 16/30] Cover XML Utils runtime edge cases --- Tests/XMLUtils/runtime.cpp | 128 +++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp index 931d674..0c9238b 100644 --- a/Tests/XMLUtils/runtime.cpp +++ b/Tests/XMLUtils/runtime.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -38,12 +39,38 @@ namespace { FailingResolver () { throw std::runtime_error ("resolver construction failed"); } }; + + struct TestIdentity : XSCRT::IdentityProvider + { + explicit TestIdentity (int value) : value (value) {} + + bool before (XSCRT::IdentityProvider const& other) const override + { + return value < static_cast (other).value; + } + + int value; + }; + + struct TestType : XSCRT::Type + { + }; } int main () { { XML::XML_Helper<> helper; + { + XML::XStr empty_xstr; + assert (empty_xstr.size () == 0); + assert (empty_xstr.end () == nullptr); + assert (!empty_xstr.append (nullptr)); + XML::XStr xstr_suffix (ACE_TEXT_ALWAYS_CHAR ("x")); + assert (empty_xstr.append (xstr_suffix.begin ())); + assert (empty_xstr.size () == 1); + } + { XSCRT::XML::string value ("copyable XML string"); XSCRT::XML::string copy (value); @@ -67,12 +94,81 @@ int main () static_cast (XML::XStr ("child")))); XSCRT::XML::Element root_element (root); + bool root_parent_rejected (false); + try + { + root_element.parent (); + } + catch (std::out_of_range const&) + { + root_parent_rejected = true; + } + assert (root_parent_rejected); + + XERCES_CPP_NAMESPACE::DOMElement const* const const_root (root); + XSCRT::XML::Element read_only_element (const_root); + bool element_mutation_rejected (false); + try + { + read_only_element.dom_element (); + } + catch (std::logic_error const&) + { + element_mutation_rejected = true; + } + assert (element_mutation_rejected); + + root->setAttribute (static_cast (XML::XStr ("name")), + static_cast (XML::XStr ("value"))); + XERCES_CPP_NAMESPACE::DOMAttr const* const const_attribute ( + root->getAttributeNode (static_cast (XML::XStr ("name")))); + XSCRT::XML::Attribute read_only_attribute (const_attribute); + bool attribute_mutation_rejected (false); + try + { + read_only_attribute.value ("replacement"); + } + catch (std::logic_error const&) + { + attribute_mutation_rejected = true; + } + assert (attribute_mutation_rejected); + XSCRT::Parser parser (root_element); assert (parser.more_elements ()); XSCRT::XML::Element child (parser.next_element ()); assert (child.name () == "child"); + assert (child.parent ().name () == "root"); assert (!parser.more_elements ()); + std::wstring wide_source; + if (sizeof (wchar_t) == 2) + { + wide_source.push_back (static_cast (0xD83D)); + wide_source.push_back (static_cast (0xDE42)); + } + else + wide_source.push_back (static_cast (0x1F642)); + + std::unique_ptr wide_xml ( + XSCRT::XML::transcode (wide_source)); + assert (XSCRT::XML::transcode ( + wide_xml.get (), static_cast (nullptr)) == wide_source); + + std::wstring invalid_wide_source; + invalid_wide_source.push_back (static_cast (0xD800)); + bool invalid_wide_rejected (false); + try + { + std::unique_ptr invalid_wide_xml ( + XSCRT::XML::transcode (invalid_wide_source)); + } + catch (std::invalid_argument const&) + { + invalid_wide_rejected = true; + } + assert (invalid_wide_rejected); + XERCES_CPP_NAMESPACE::DOMDocument* const generated_document = helper.create_dom (ACE_TEXT ("document"), ACE_TEXT ("urn:xsc:xml-utils-test")); XERCES_CPP_NAMESPACE::DOMElement* const generated_root ( @@ -213,4 +309,36 @@ int main () string_traverser.dispatch (token); assert (string_traverser.visits == 1); } + + { + TestType type; + TestIdentity identity (1); + type.register_id (identity, std::addressof (type)); + assert (type.lookup_id (identity) == std::addressof (type)); + + bool duplicate_rejected (false); + try + { + type.register_id (identity, std::addressof (type)); + } + catch (std::logic_error const&) + { + duplicate_rejected = true; + } + assert (duplicate_rejected); + + type.unregister_id (identity); + assert (type.lookup_id (identity) == nullptr); + + bool missing_rejected (false); + try + { + type.unregister_id (identity); + } + catch (std::logic_error const&) + { + missing_rejected = true; + } + assert (missing_rejected); + } } From ad81765f7926c0996dc23d4d0d07e71ba162b365 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 10:46:25 +0100 Subject: [PATCH 17/30] Test XML ID assignment rollback --- Tests/XMLUtils/runtime.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp index 0c9238b..75290b1 100644 --- a/Tests/XMLUtils/runtime.cpp +++ b/Tests/XMLUtils/runtime.cpp @@ -341,4 +341,29 @@ int main () } assert (missing_rejected); } + + { + TestType root; + XMLSchema::ID first (std::string ("first")); + XMLSchema::ID second (std::string ("second")); + first.container (std::addressof (root)); + second.container (std::addressof (root)); + + bool duplicate_rejected (false); + try + { + first = second; + } + catch (std::logic_error const&) + { + duplicate_rejected = true; + } + + assert (duplicate_rejected); + assert (first == "first"); + assert (second == "second"); + + first = std::string ("third"); + assert (first == "third"); + } } From dfa62b1480544250afe4b21f96ef8a0f6fa7cb98 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 11:36:47 +0100 Subject: [PATCH 18/30] Test duplicate XML ID registration failures --- .gitignore | 1 + Tests/XMLUtils/run_test.pl | 30 +++++++++++----------- Tests/XMLUtils/runtime.cpp | 18 ++++++++++++++ Tests/XMLUtils/runtime.mpc | 6 +++++ Tests/XMLUtils/xscrt_registration.cpp | 36 +++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 Tests/XMLUtils/xscrt_registration.cpp diff --git a/.gitignore b/.gitignore index d6026b2..3055f61 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,7 @@ Release/ /Tests/XMLUtils/generated_types.cpp /Tests/XMLUtils/generated_types.hpp /Tests/XMLUtils/runtime +/Tests/XMLUtils/xscrt_registration /abstract.cpp /abstract.hpp /dds_qos.cpp diff --git a/Tests/XMLUtils/run_test.pl b/Tests/XMLUtils/run_test.pl index 30aba3b..79ab254 100644 --- a/Tests/XMLUtils/run_test.pl +++ b/Tests/XMLUtils/run_test.pl @@ -11,22 +11,24 @@ my $target = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; -my $test = "$ENV{XSC_ROOT}/Tests/XMLUtils/runtime"; -unless (-x $test) { - die "ERROR: Cannot find executable $test\n"; -} +for my $name (qw(runtime xscrt_registration)) { + my $test = "$ENV{XSC_ROOT}/Tests/XMLUtils/$name"; + unless (-x $test) { + die "ERROR: Cannot find executable $test\n"; + } -my $process = $target->CreateProcess ($test); -my $result = $process->SpawnWaitKill ($target->ProcessStartWaitInterval ()); + my $process = $target->CreateProcess ($test); + my $result = $process->SpawnWaitKill ($target->ProcessStartWaitInterval ()); -if ($result == -1) { - print STDERR "ERROR: ACE XML_Utils runtime regression timed out\n"; - exit 1; -} -elsif ($result != 0) { - print STDERR "ERROR: ACE XML_Utils runtime regression failed with status $result\n"; - exit 1; + if ($result == -1) { + print STDERR "ERROR: ACE XML_Utils $name regression timed out\n"; + exit 1; + } + elsif ($result != 0) { + print STDERR "ERROR: ACE XML_Utils $name regression failed with status $result\n"; + exit 1; + } } -print "ACE XML_Utils runtime regression passed\n"; +print "ACE XML_Utils runtime regressions passed\n"; exit 0; diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp index 75290b1..610271c 100644 --- a/Tests/XMLUtils/runtime.cpp +++ b/Tests/XMLUtils/runtime.cpp @@ -366,4 +366,22 @@ int main () first = std::string ("third"); assert (first == "third"); } + + { + TestType root; + XMLSchema::ID existing (std::string ("duplicate")); + XMLSchema::ID rejected (std::string ("duplicate")); + existing.container (std::addressof (root)); + + bool duplicate_rejected (false); + try + { + rejected.container (std::addressof (root)); + } + catch (std::logic_error const&) + { + duplicate_rejected = true; + } + assert (duplicate_rejected); + } } diff --git a/Tests/XMLUtils/runtime.mpc b/Tests/XMLUtils/runtime.mpc index cf4c558..c46bef1 100644 --- a/Tests/XMLUtils/runtime.mpc +++ b/Tests/XMLUtils/runtime.mpc @@ -23,3 +23,9 @@ project (xsc_test_xml_utils_runtime_generated): xscrt, ace_xml_utils { generated_types.cpp } } + +project (xsc_test_xml_utils_xscrt_registration): ace_xml_utils { + Source_Files { + xscrt_registration.cpp + } +} diff --git a/Tests/XMLUtils/xscrt_registration.cpp b/Tests/XMLUtils/xscrt_registration.cpp new file mode 100644 index 0000000..9079571 --- /dev/null +++ b/Tests/XMLUtils/xscrt_registration.cpp @@ -0,0 +1,36 @@ +#include + +#include +#include +#include +#include + +namespace +{ + struct TestType : XSCRT::Type + { + }; +} + +int main () +{ + XSCRT::ExtendedTypeInfoMap type_info; + XMLSchema::TypeInfoInitializer initialize (type_info); + + TestType root; + XMLSchema::ID existing (std::string ("duplicate")); + XMLSchema::ID rejected (std::string ("duplicate")); + existing.container (std::addressof (root)); + + bool duplicate_rejected (false); + try + { + rejected.container (std::addressof (root)); + } + catch (std::logic_error const&) + { + duplicate_rejected = true; + } + + assert (duplicate_rejected); +} From 3274bf475c1c91d50e4ebf4537fd62e941107d3b Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 13:13:18 +0100 Subject: [PATCH 19/30] Default empty constructors --- XSC/Parser.hpp | 4 +--- XSC/SemanticGraph/Context.hpp | 4 +--- XSC/utils/XercesString.cpp | 5 +---- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/XSC/Parser.hpp b/XSC/Parser.hpp index d41bb92..8ed01ba 100644 --- a/XSC/Parser.hpp +++ b/XSC/Parser.hpp @@ -23,9 +23,7 @@ namespace XSC class string : public std::wstring { public: - string () - { - } + string () = default; string (wchar_t const* s) : std::wstring (s) diff --git a/XSC/SemanticGraph/Context.hpp b/XSC/SemanticGraph/Context.hpp index 69013b5..b2eaaef 100644 --- a/XSC/SemanticGraph/Context.hpp +++ b/XSC/SemanticGraph/Context.hpp @@ -17,9 +17,7 @@ namespace XSC using Map = std::map; public: - Context () - { - } + Context () = default; public: class NotFound {}; diff --git a/XSC/utils/XercesString.cpp b/XSC/utils/XercesString.cpp index e8ca7f9..e2d3469 100644 --- a/XSC/utils/XercesString.cpp +++ b/XSC/utils/XercesString.cpp @@ -11,10 +11,7 @@ namespace XSC // // XStr // -XStr::XStr () -{ - -} +XStr::XStr () = default; // // XStr From 75372e35d12d1d451f85bde417fb78039274d032 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 13:21:27 +0100 Subject: [PATCH 20/30] Use ACE Xerces string utility --- MPC/config/xsc_utils.mpb | 2 +- XSC/utils/XML_Error_Handler.cpp | 9 +- XSC/utils/XML_Error_Handler.h | 8 +- XSC/utils/XML_Schema_Resolver.cpp | 20 +- XSC/utils/XML_Schema_Resolver.h | 30 ++- XSC/utils/XSC_Utils.mpc | 3 +- XSC/utils/XercesString.cpp | 314 ------------------------------ XSC/utils/XercesString.h | 73 ------- 8 files changed, 32 insertions(+), 427 deletions(-) delete mode 100644 XSC/utils/XercesString.cpp delete mode 100644 XSC/utils/XercesString.h diff --git a/MPC/config/xsc_utils.mpb b/MPC/config/xsc_utils.mpb index 5db691d..0cdf2b6 100644 --- a/MPC/config/xsc_utils.mpb +++ b/MPC/config/xsc_utils.mpb @@ -1,4 +1,4 @@ -project : xsc_common { +project : xsc_common, ace_xml_utils { after += XSC_Utils libs += XSC_Utils } diff --git a/XSC/utils/XML_Error_Handler.cpp b/XSC/utils/XML_Error_Handler.cpp index f1baabc..59ab485 100644 --- a/XSC/utils/XML_Error_Handler.cpp +++ b/XSC/utils/XML_Error_Handler.cpp @@ -2,11 +2,8 @@ #include "xercesc/util/XMLString.hpp" #include "xercesc/dom/DOMLocator.hpp" #include "xercesc/sax/SAXParseException.hpp" -#include "XercesString.h" #include -using xercesc::SAXParseException; - namespace XSC { namespace XML @@ -15,7 +12,7 @@ namespace XSC XML_Error_Handler::~XML_Error_Handler() = default; - void XML_Error_Handler::warning(const SAXParseException& toCatch) + void XML_Error_Handler::warning(const xercesc::SAXParseException& toCatch) { char * file = xercesc::XMLString::transcode (toCatch.getSystemId ()); char * msg = xercesc::XMLString::transcode (toCatch.getMessage ()); @@ -28,7 +25,7 @@ namespace XSC xercesc::XMLString::release (&msg); } - void XML_Error_Handler::error(const SAXParseException& toCatch) + void XML_Error_Handler::error(const xercesc::SAXParseException& toCatch) { char * file = xercesc::XMLString::transcode (toCatch.getSystemId ()); char * msg = xercesc::XMLString::transcode (toCatch.getMessage ()); @@ -43,7 +40,7 @@ namespace XSC xercesc::XMLString::release (&msg); } - void XML_Error_Handler::fatalError(const SAXParseException& toCatch) + void XML_Error_Handler::fatalError(const xercesc::SAXParseException& toCatch) { char * file = xercesc::XMLString::transcode (toCatch.getSystemId ()); char * msg = xercesc::XMLString::transcode (toCatch.getMessage ()); diff --git a/XSC/utils/XML_Error_Handler.h b/XSC/utils/XML_Error_Handler.h index 924833d..56b0c91 100644 --- a/XSC/utils/XML_Error_Handler.h +++ b/XSC/utils/XML_Error_Handler.h @@ -13,8 +13,6 @@ #include "XSC_Utils_export.h" #include "xercesc/sax/ErrorHandler.hpp" -using xercesc::SAXParseException; - namespace XSC { namespace XML @@ -34,9 +32,9 @@ namespace XSC ~XML_Error_Handler () override; - void warning(const SAXParseException& toCatch) override; - void error(const SAXParseException& toCatch) override; - void fatalError(const SAXParseException& toCatch) override; + void warning(const xercesc::SAXParseException& toCatch) override; + void error(const xercesc::SAXParseException& toCatch) override; + void fatalError(const xercesc::SAXParseException& toCatch) override; void resetErrors() override; bool getErrors () const noexcept; private : diff --git a/XSC/utils/XML_Schema_Resolver.cpp b/XSC/utils/XML_Schema_Resolver.cpp index 6934e7d..5c7338a 100644 --- a/XSC/utils/XML_Schema_Resolver.cpp +++ b/XSC/utils/XML_Schema_Resolver.cpp @@ -1,7 +1,7 @@ #ifndef XML_SCHEMA_RESOLVER_TPP #define XML_SCHEMA_RESOLVER_TPP -#include "XercesString.h" +#include "ace/XML_Utils/XercesString.h" #include "xercesc/util/PlatformUtils.hpp" #include "xercesc/util/XercesDefs.hpp" #include "xercesc/framework/LocalFileInputSource.hpp" @@ -21,7 +21,7 @@ namespace XSC /// This function is called by the Xerces infrastructure to /// actually resolve the location of a schema. template - InputSource * + xercesc::InputSource * XML_Schema_Resolver::resolveEntity (const XMLCh *const publicId, const XMLCh *const systemId) { @@ -47,11 +47,11 @@ namespace XSC } template - InputSource * + xercesc::InputSource * Basic_Resolver ::operator() (const XMLCh *const publicId, const XMLCh *const systemId) const { - XStr path (path_); + ::XML::XStr path (path_); path.append (systemId); return new xercesc::LocalFileInputSource (path); @@ -74,14 +74,14 @@ namespace XSC if (item.empty ()) return false; - XStr path (item.c_str ()); + ::XML::XStr path (item.c_str ()); path.append (this->systemId_); - FileHandle file (XMLPlatformUtils::openFile (path)); + xercesc::FileHandle file (xercesc::XMLPlatformUtils::openFile (path)); bool retval = file != nullptr; if (retval) - XMLPlatformUtils::closeFile (file); + xercesc::XMLPlatformUtils::closeFile (file); return retval; } @@ -107,7 +107,7 @@ namespace XSC } template - InputSource * + xercesc::InputSource * Path_Resolver ::operator() (const XMLCh *const, const XMLCh *const systemId) const { @@ -118,7 +118,7 @@ namespace XSC if (iter != this->paths_.end ()) { - XStr path (iter->c_str ()); + ::XML::XStr path (iter->c_str ()); path.append (systemId); return new xercesc::LocalFileInputSource (path); } @@ -159,7 +159,7 @@ namespace XSC } template - InputSource * URL_Resolver :: + xercesc::InputSource * URL_Resolver :: operator() (const XMLCh *const publicId, const XMLCh *const systemId) const { xercesc::XMLURL url (this->url_, systemId); diff --git a/XSC/utils/XML_Schema_Resolver.h b/XSC/utils/XML_Schema_Resolver.h index 8e76200..9b23343 100644 --- a/XSC/utils/XML_Schema_Resolver.h +++ b/XSC/utils/XML_Schema_Resolver.h @@ -9,14 +9,12 @@ #define CIAO_XML_SCHEMA_RESOLVER_H #include "XSC_Utils_export.h" -#include "XercesString.h" +#include "ace/XML_Utils/XercesString.h" #include "xercesc/sax/EntityResolver.hpp" #include "ace/ace_wchar.h" #include #include -using namespace xercesc; - namespace XSC { namespace XML @@ -33,15 +31,15 @@ namespace XSC */ template class XML_Schema_Resolver - : public virtual EntityResolver + : public virtual xercesc::EntityResolver { public: XML_Schema_Resolver (Resolver &resolver); /// This function is called by the Xerces infrastructure to /// actually resolve the location of a schema. - InputSource * resolveEntity (const XMLCh *const publicId, - const XMLCh *const systemId) override; + xercesc::InputSource * resolveEntity (const XMLCh *const publicId, + const XMLCh *const systemId) override; private: XML_Schema_Resolver () = delete; @@ -59,8 +57,8 @@ namespace XSC */ struct NoOp_Resolver { - InputSource * operator() (const XMLCh *const, - const XMLCh *const) const + xercesc::InputSource * operator() (const XMLCh *const, + const XMLCh *const) const { return nullptr; }; }; @@ -90,8 +88,8 @@ namespace XSC * @param[in] publicId Public Id of the definition * @param[in] systemId System Id of the definition */ - InputSource * operator () (const XMLCh *const publicId, - const XMLCh *const systemId) const; + xercesc::InputSource * operator () (const XMLCh *const publicId, + const XMLCh *const systemId) const; /** * Update the path of the definitions @@ -102,7 +100,7 @@ namespace XSC private: /// Path for resolving schema definitions - XStr path_; + ::XML::XStr path_; }; /** @@ -113,10 +111,10 @@ namespace XSC { URL_Resolver (const CHAR *url); - InputSource * operator() (const XMLCh *const publicId, - const XMLCh *const systemId) const; + xercesc::InputSource * operator() (const XMLCh *const publicId, + const XMLCh *const systemId) const; private: - XStr url_; + ::XML::XStr url_; }; /** @@ -134,8 +132,8 @@ namespace XSC void insert (const CHAR *path); - InputSource * operator() (const XMLCh *const publicId, - const XMLCh *const systemId) const; + xercesc::InputSource * operator() (const XMLCh *const publicId, + const XMLCh *const systemId) const; private: /// Paths to search for schema definitions. diff --git a/XSC/utils/XSC_Utils.mpc b/XSC/utils/XSC_Utils.mpc index d52bae9..a3ecf3d 100644 --- a/XSC/utils/XSC_Utils.mpc +++ b/XSC/utils/XSC_Utils.mpc @@ -1,9 +1,8 @@ -project (XSC_Utils) : acelib, xsc_common { +project (XSC_Utils) : acelib, xsc_common, ace_xml_utils { sharedname = XSC_Utils dynamicflags += XSC_UTILS_BUILD_DLL Source_Files { - XercesString.cpp XML_Error_Handler.cpp } diff --git a/XSC/utils/XercesString.cpp b/XSC/utils/XercesString.cpp deleted file mode 100644 index e2d3469..0000000 --- a/XSC/utils/XercesString.cpp +++ /dev/null @@ -1,314 +0,0 @@ -#include "XercesString.h" -#include -#include -#include - -using xercesc::XMLString; - -namespace XSC -{ - -// -// XStr -// -XStr::XStr () = default; - -// -// XStr -// -XStr::XStr (const char* str) -{ - this->wstr_ = XMLString::transcode (str); -} - -// -// XStr -// -XStr::XStr (XMLCh *wstr) -{ - this->wstr_ = XMLString::replicate (wstr); -} - -// -// XStr -// -XStr::XStr (const XMLCh* wstr) -{ - this->wstr_ = XMLString::replicate (wstr); -} - -// -// XStr -// -XStr::XStr (const XStr &right) -{ - this->wstr_ = XMLString::replicate (right.wstr_); -} - -// -// XStr -// -XStr::XStr (XStr&& right) noexcept - : wstr_ (std::exchange (right.wstr_, nullptr)), - cstr_ (std::exchange (right.cstr_, nullptr)) -{ -} - -// -// ~XStr -// -XStr::~XStr () -{ - if (this->wstr_ != nullptr) - XMLString::release (&this->wstr_); - - if (this->cstr_ != nullptr) - XMLString::release (&this->cstr_); -} - -// -// operator = -// -XStr& XStr::operator = (const XStr& rhs) -{ - if (&rhs == this) - return *this; - - XStr temp (rhs); - std::swap (this->wstr_, temp.wstr_); - std::swap (this->cstr_, temp.cstr_); - - return *this; -} - -// -// operator = -// -XStr& XStr::operator = (XStr&& rhs) noexcept -{ - if (&rhs == this) - return *this; - - if (this->wstr_ != nullptr) - XMLString::release (&this->wstr_); - - if (this->cstr_ != nullptr) - XMLString::release (&this->cstr_); - - this->wstr_ = std::exchange (rhs.wstr_, nullptr); - this->cstr_ = std::exchange (rhs.cstr_, nullptr); - - return *this; -} - -// -// operator = -// -XStr& XStr::operator = (const char * rhs) -{ - XStr temp (rhs); - std::swap (this->wstr_, temp.wstr_); - std::swap (this->cstr_, temp.cstr_); - - return *this; -} - -// -// begin -// -const XMLCh* XStr::begin () const -{ - return this->wstr_; -} - -// -// end -// -const XMLCh* XStr::end () const -{ - return this->wstr_ + this->size (); -} - -// -// append -// -bool XStr::append (const XMLCh *tail) -{ - using namespace xercesc; - - int iTailLen = XMLString::stringLen (tail); - int iWorkLen = XMLString::stringLen (this->wstr_); - size_t length = iWorkLen + iTailLen + 1; - - XMLCh * result = - static_cast (XMLPlatformUtils::fgMemoryManager->allocate ( - length * sizeof (XMLCh))); - - bool bOK = result != nullptr; - - if (bOK) - { - XMLCh *target = result; - - XMLString::moveChars (target, this->wstr_, iWorkLen); - target += iWorkLen; - - XMLString::moveChars (target, tail, iTailLen); - target += iTailLen; - - *target++ = 0; - - XMLString::release (&this->wstr_); - this->wstr_ = result; - - if (this->cstr_ != nullptr) - { - XMLString::release (&this->cstr_); - this->cstr_ = nullptr; - } - } - - return bOK; -} - -// -// erase -// -bool XStr::erase (const XMLCh *head, const XMLCh *tail) -{ - bool bOK = head <= tail && head >= begin() && tail <= end(); - if (bOK) - { - const std::size_t length = size () - (tail - head) + 1; - XMLCh *result = - static_cast (xercesc::XMLPlatformUtils::fgMemoryManager->allocate ( - length * sizeof (XMLCh))); - XMLCh *target = result; - bOK = target != nullptr; - - if (bOK) - { - const XMLCh *cursor = begin(); - - while (cursor != head) *target++ = *cursor++; - cursor = tail; - while ( cursor != end() ) *target++ = *cursor++; - *target ++ = 0; - - XMLString::release (&this->wstr_); - this->wstr_ = result; - - if (this->cstr_ != nullptr) - { - XMLString::release (&this->cstr_); - this->cstr_ = nullptr; - } - } - } - return bOK; -} - -// -// size -// -int XStr::size () const -{ - return XMLString::stringLen (this->wstr_); -} - -// -// operator [] -// -XMLCh XStr::operator [] (const int i) -{ - return this->wstr_[i]; -} - -// -// operator [] -// -XMLCh XStr::operator [] (const int i) const -{ - return this->wstr_[i]; -} - -// -// release -// -XMLCh * XStr::release () -{ - XMLCh * temp = this->wstr_; - this->wstr_ = nullptr; - - // Release the C string. - if (this->cstr_ != nullptr) - { - XMLString::release (&this->cstr_); - this->cstr_ = nullptr; - } - - return temp; -} - -// -// c_str -// -const char * XStr::c_str () -{ - if (this->cstr_ != nullptr) - return this->cstr_; - - this->cstr_ = XMLString::transcode (this->wstr_); - return this->cstr_; -} - -} - - -// -// operator == -// -bool operator == (const XSC::XStr & lhs, const XSC::XStr & rhs) -{ - return 0 == XMLString::compareString (lhs, rhs); -} - -// -// operator == -// -bool operator == (const XSC::XStr & lhs, const XMLCh * rhs) -{ - return 0 == XMLString::compareString (lhs, rhs); -} - -// -// operator == -// -bool operator == (const XMLCh * lhs, const XSC::XStr & rhs) -{ - return 0 == XMLString::compareString (lhs, rhs); -} - -// -// operator != -// -bool operator != (const XSC::XStr & lhs, const XSC::XStr & rhs) -{ - return !(lhs == rhs); -} - -// -// operator != -// -bool operator != (const XMLCh * lhs, const XSC::XStr & rhs) -{ - return !(lhs == rhs); -} - -// -// operator != -// -bool operator != (const XSC::XStr & lhs, const XMLCh * rhs) -{ - return !(lhs == rhs); -} diff --git a/XSC/utils/XercesString.h b/XSC/utils/XercesString.h deleted file mode 100644 index d44983c..0000000 --- a/XSC/utils/XercesString.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _XERCESSTRING_H -#define _XERCESSTRING_H - -#include "XSC_Utils_export.h" -#include "xercesc/util/XMLString.hpp" -#include - -// Utility class that provides a std::string like facade to XMLString. -// Doesn't implement all of the methods of std::string. -namespace XSC -{ - class XSC_UTILS_Export XStr - { - public: - XStr (); - - XStr (const char* str); - - XStr (XMLCh* wstr); - - XStr (const XMLCh* wstr); - - XStr (const XStr& copy); - - XStr (XStr&&) noexcept; - - XStr& operator= (const XStr& rhs); - - XStr& operator= (XStr&&) noexcept; - - XStr& operator= (const char * rhs); - - ~XStr(); - - const XMLCh* begin() const; - - const XMLCh* end() const; - - bool append(const XMLCh* tail); - - bool erase (const XMLCh* head, const XMLCh* tail); - - int size() const; - - XMLCh operator [] (const int i); - - XMLCh operator [] (const int i) const; - - operator const XMLCh* () const { return wstr_; }; - - XMLCh * release (); - - /// Get the C string version of the XercesString. - const char * c_str (); - - private: - /// Internal representation - XMLCh* wstr_ {}; - - /// The C string version of the XercesString. - char * cstr_ {}; - }; -} - -XSC_UTILS_Export bool operator == (const XSC::XStr & lhs, const XSC::XStr & rhs); -XSC_UTILS_Export bool operator == (const XMLCh * lhs, const XSC::XStr & rhs); -XSC_UTILS_Export bool operator == (const XSC::XStr & lhs, const XMLCh * rhs); - -XSC_UTILS_Export bool operator != (const XSC::XStr & lhs, const XSC::XStr & rhs); -XSC_UTILS_Export bool operator != (const XMLCh * lhs, const XSC::XStr & rhs); -XSC_UTILS_Export bool operator != (const XSC::XStr & lhs, const XMLCh * rhs); - -#endif /* _XERCESSTRING_H */ From e06cce3f0ceabd2ac8a3298deed6150dc67e588b Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 13:33:37 +0100 Subject: [PATCH 21/30] Modernize XSC traversal loops --- XSC/Parser.cpp | 36 ------------ XSC/Parser.hpp | 10 ---- XSC/SemanticGraph/Attribute.cpp | 2 - XSC/SemanticGraph/Element.cpp | 2 - XSC/SemanticGraph/Elements.cpp | 22 ------- XSC/SemanticGraph/Elements.hpp | 26 --------- XSC/SemanticGraph/Enumeration.cpp | 4 -- XSC/SemanticGraph/Fundamental.cpp | 65 --------------------- XSC/SemanticGraph/Fundamental.hpp | 97 ------------------------------- XSC/SemanticGraph/Graph.tpp | 4 -- XSC/SemanticGraph/Schema.cpp | 11 ---- XSC/SemanticGraph/Schema.hpp | 16 +---- XSC/Traversal/Attribute.cpp | 2 - XSC/Traversal/Attribute.hpp | 3 - XSC/Traversal/Elements.cpp | 2 - XSC/Traversal/Elements.hpp | 54 ++--------------- XSC/Traversal/Elements.tpp | 27 +++------ XSC/Traversal/Enumeration.cpp | 4 -- XSC/Traversal/Schema.hpp | 15 ----- XSC/be/CXX/Elements.cpp | 6 -- XSC/be/CXX/Elements.hpp | 8 --- XSC/be/CXX/Generator.cpp | 22 +------ XSC/be/CXX/Generator.hpp | 1 - XSC/be/CXX/Header.cpp | 12 ---- XSC/be/CXX/Inline.cpp | 20 ------- XSC/be/CXX/Source.cpp | 51 ++++++---------- XSC/be/CXX/TraversalHeader.cpp | 19 ------ XSC/be/CXX/TraversalSource.cpp | 28 --------- XSC/be/CXX/TypeInfoSource.cpp | 2 - XSC/be/CXX/Validator.cpp | 2 - XSC/be/CXX/WriterHeader.cpp | 15 ----- XSC/be/CXX/WriterSource.cpp | 18 ------ XSC/be/IDL/Definition.cpp | 3 - XSC/be/IDL/Elements.cpp | 8 --- XSC/be/IDL/Elements.hpp | 9 --- XSC/be/IDL/Generator.cpp | 14 +---- XSC/be/IDL/Generator.hpp | 1 - XSC/xsc.cpp | 4 -- 38 files changed, 37 insertions(+), 608 deletions(-) diff --git a/XSC/Parser.cpp b/XSC/Parser.cpp index 700a99a..b3986f4 100644 --- a/XSC/Parser.cpp +++ b/XSC/Parser.cpp @@ -170,7 +170,6 @@ namespace XSC Scope& scope (resolve (ns_name, uq_name, schema_)); // @@ same code as in Parser::group - // for (Scope::NamesIterator i (scope.names_begin ()); i != scope.names_end (); ++i) { @@ -183,12 +182,9 @@ namespace XSC schema_.new_edge (c, e, prot.name ()); // Now we set element's type. - // - // if (prot.typed ()) { // Easy case. - // schema_.new_edge (e, prot.type ()); } else if (prot.context ().count ("type-ns-name")) @@ -210,7 +206,6 @@ namespace XSC else { // What the heck? - // if (trace_) std::wcout << "element `" << ns_name << "#" << uq_name << "' is in unexpected condition" << std::endl; @@ -237,7 +232,6 @@ namespace XSC } // We don't need to go inside enumerations. - // void traverse (SemanticGraph::Enumeration&) override { @@ -261,7 +255,6 @@ namespace XSC std::unique_ptr rs (std::make_unique ()); // Implied schema with fundamental types. - // { Schema& s (rs->new_node ()); rs->new_edge (*rs, s, std::filesystem::path ("XMLSchema.xsd")); @@ -320,7 +313,6 @@ namespace XSC } // Parse. - // if (DOMDocument* d = dom (uri)) { XML::Element root (d->getDocumentElement ()); @@ -330,7 +322,6 @@ namespace XSC if (trace_) std::wcout << "target namespace: " << ns << std::endl; // Enter the file into file_map_. - // file_map_[uri] = ns; root_schema_ = cur_schema_ = rs.get (); @@ -347,10 +338,8 @@ namespace XSC } //@@ don't need this in case of an error - // // Second pass to resolve types and refs. - // { Traversal::Schema schema; Traversal::Contains contains; @@ -538,7 +527,6 @@ namespace XSC { // Chameleon. - // // @@Will: What is a chameleon schema? ns = cur_ns; root_schema_->new_edge (*cur_schema_, s, path); @@ -611,7 +599,6 @@ namespace XSC string ns_name (XML::ns_name (g, ref)); //@@ min/max - // // min/max can come from element in the group! unsigned long min (g[L"minOccurs"] == L"0" ? 0 : this->min ()), @@ -636,11 +623,9 @@ namespace XSC root_schema_->new_edge (scope (), e, prot.name ()); // Now we set element's type. - // if (prot.typed ()) { // Easy case. - // root_schema_->new_edge (e, prot.type ()); } else if (prot.context ().count ("type-ns-name")) @@ -662,7 +647,6 @@ namespace XSC else { // What the heck? - // if (trace_) std::wcout << "element `" << ref << "' is in unexpected condition" << std::endl; @@ -683,7 +667,6 @@ namespace XSC // Cannot resolve group at this point. Will have to try later. // The tricky part is that we have to save position where we will // be inserting elements. - // scope ().context ().set ("group-ns-name", ns_name); scope ().context ().set ("group-uq-name", uq_name); @@ -715,7 +698,6 @@ namespace XSC } //@@ need RAII for push/pop - // Type* Parser:: simple_type (XML::Element const& t, const string& anon_name) @@ -767,7 +749,6 @@ namespace XSC if (e.name () == L"enumeration") { // Enumeration - // enum_ = true; Enumeration& node (root_schema_->new_node ()); @@ -798,7 +779,6 @@ namespace XSC if (!enum_) { //Complex& node (root_schema_->new_node ()); - // //set_type (r[L"base"], r, node); // base is likely a fundamental type? @@ -836,7 +816,6 @@ namespace XSC // if (more ()) // { // XML::Element e (next ()); -// // string base1 (fq_name (e, e[L"base"])); // std::wcout << "restriction base: " << base1 << std::endl; // } @@ -933,7 +912,6 @@ namespace XSC // can it contain any of those. The default cardinality // values for `all' are min=1, max=1. Therefore we don't // really need to push/pop cardinality. - // this->push (a); this->annotation (); @@ -1015,7 +993,6 @@ namespace XSC sequence (XML::Element const& s) { // Establish cardinality. - // push_cardinality (s[L"minOccurs"] == L"0" ? 0 : min (), s[L"maxOccurs"] && s[L"maxOccurs"] != L"1" ? 0 : max ()); @@ -1236,7 +1213,6 @@ namespace XSC else { // anyType almighty. - // string prefix (ns_prefix (e, xsd)); type = prefix + (prefix.empty () ? L"" : L":") + L"anyType"; @@ -1275,11 +1251,9 @@ namespace XSC << "deferring resolution until later" << std::endl; } // Global element cannot reference. - // else { // What the heck? - // if (trace_) std::wcout << "element `" << ref << "' is in unexpected condition" << std::endl; @@ -1531,51 +1505,41 @@ namespace XSC } // Initialize Xerces runtime - // XMLPlatformUtils::Initialize(); XercesDOMParser parser; // Discard comment nodes in the document. - // parser.setCreateCommentNodes (false); // Disable datatype normalization. The XML 1.0 attribute value // normalization always occurs though. - // //parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true); // Do not create EntityReference nodes in the DOM tree. No // EntityReference nodes will be created, only the nodes // Corresponding to their fully expanded substitution text will be // created. - // parser.setCreateEntityReferenceNodes (false); // Perform Namespace processing. - // parser.setDoNamespaces (true); // Perform Validation - // //parser.setValidationScheme (true); // Do not include ignorable whitespace in the DOM tree. - // parser.setIncludeIgnorableWhitespace (false); // Enable the parser's schema support. - // parser.setDoSchema (true); // Enable full schema constraint checking, including checking which // may be time-consuming or memory intensive. Currently, particle // unique attribution constraint checking and particle derivation // restriction checking are controlled by this option. - // parser.setValidationSchemaFullChecking (true); // The parser will treat validation error as fatal and will exit. - // parser.setValidationConstraintFatal (true); // Setup the error handler. diff --git a/XSC/Parser.hpp b/XSC/Parser.hpp index 8ed01ba..dd70f23 100644 --- a/XSC/Parser.hpp +++ b/XSC/Parser.hpp @@ -186,7 +186,6 @@ namespace XSC } //@@ can get rid of use_default crap. See XSCRT. - // inline string ns_prefix (Element const& e, @@ -410,14 +409,8 @@ namespace XSC SemanticGraph::Schema* cur_schema_ {}; // current schema file - // - // - // std::stack scope_stack_; - // - // - // struct Cardinality { Cardinality (unsigned long min, unsigned long max) @@ -431,9 +424,6 @@ namespace XSC std::stack cardinality_stack_; - // - // - // struct FilePathComparator { bool operator () (std::filesystem::path const& x, std::filesystem::path const& y) const diff --git a/XSC/SemanticGraph/Attribute.cpp b/XSC/SemanticGraph/Attribute.cpp index 6d0e930..e27c86b 100644 --- a/XSC/SemanticGraph/Attribute.cpp +++ b/XSC/SemanticGraph/Attribute.cpp @@ -11,8 +11,6 @@ namespace XSC using Introspection::Access; // Attribute - // - // namespace { TypeInfo diff --git a/XSC/SemanticGraph/Element.cpp b/XSC/SemanticGraph/Element.cpp index b9b86c3..8c8d79d 100644 --- a/XSC/SemanticGraph/Element.cpp +++ b/XSC/SemanticGraph/Element.cpp @@ -11,8 +11,6 @@ namespace XSC using Introspection::Access; // Element - // - // namespace { TypeInfo diff --git a/XSC/SemanticGraph/Elements.cpp b/XSC/SemanticGraph/Elements.cpp index 8b1ece0..81b2cd8 100644 --- a/XSC/SemanticGraph/Elements.cpp +++ b/XSC/SemanticGraph/Elements.cpp @@ -11,8 +11,6 @@ namespace XSC using Introspection::Access; // Edge - // - // namespace { TypeInfo @@ -32,8 +30,6 @@ namespace XSC // Node - // - // namespace { TypeInfo @@ -53,8 +49,6 @@ namespace XSC // Names - // - // namespace { TypeInfo @@ -72,8 +66,6 @@ namespace XSC static_type_info () { return names_; } // Nameable - // - // namespace { TypeInfo @@ -93,8 +85,6 @@ namespace XSC // Scope - // - // namespace { TypeInfo @@ -113,8 +103,6 @@ namespace XSC // Type - // - // namespace { TypeInfo @@ -133,8 +121,6 @@ namespace XSC // Instance - // - // Type& Instance:: type () const @@ -160,8 +146,6 @@ namespace XSC // Belongs - // - // namespace { TypeInfo @@ -180,8 +164,6 @@ namespace XSC // Inherits - // - // namespace { TypeInfo @@ -200,8 +182,6 @@ namespace XSC // Contains - // - // namespace { TypeInfo @@ -220,8 +200,6 @@ namespace XSC // Container - // - // namespace { TypeInfo diff --git a/XSC/SemanticGraph/Elements.hpp b/XSC/SemanticGraph/Elements.hpp index 0156745..a0872da 100644 --- a/XSC/SemanticGraph/Elements.hpp +++ b/XSC/SemanticGraph/Elements.hpp @@ -19,16 +19,11 @@ namespace XSC { namespace SemanticGraph { - // - // - // class Node; class Edge; // Node & Edge - // - // class Edge : public virtual Introspection::Object { public: @@ -103,7 +98,6 @@ namespace XSC // This is a bunch of experimental sink functions that allow // extensions in the form of one-way edges (see Executor stuff // in CIDL for example). - // //void //add_edge_left (Edge&) //{ @@ -124,14 +118,8 @@ namespace XSC return std::addressof (x) == std::addressof (y); } - // - // - // using Name_ = std::wstring; - // - // - // class Scope; class Nameable; @@ -262,9 +250,6 @@ namespace XSC using Nameables = std::set; - // - // - // class Scope : public virtual Nameable { protected: @@ -272,8 +257,6 @@ namespace XSC using NamesMap_ = std::map; public: - // - // using NamesIterator = Names_::const_iterator; using NamesIteratorPair = std::pair; @@ -332,9 +315,6 @@ namespace XSC - // - // - // class Belongs; class Type : public virtual Nameable @@ -454,9 +434,6 @@ namespace XSC }; - // - // - // class Inherits : public virtual Edge { public: @@ -501,9 +478,6 @@ namespace XSC }; - // - // - // class Container; class Contains : public virtual Edge diff --git a/XSC/SemanticGraph/Enumeration.cpp b/XSC/SemanticGraph/Enumeration.cpp index d6fdde1..32099f4 100644 --- a/XSC/SemanticGraph/Enumeration.cpp +++ b/XSC/SemanticGraph/Enumeration.cpp @@ -11,8 +11,6 @@ namespace XSC using Introspection::Access; // Enum - // - // namespace { TypeInfo @@ -31,8 +29,6 @@ namespace XSC // Enumerator - // - // namespace { TypeInfo diff --git a/XSC/SemanticGraph/Fundamental.cpp b/XSC/SemanticGraph/Fundamental.cpp index 5e38eb3..bc094ee 100644 --- a/XSC/SemanticGraph/Fundamental.cpp +++ b/XSC/SemanticGraph/Fundamental.cpp @@ -2,7 +2,6 @@ // author : Boris Kolpackov // Note, that this file is automatically generated! -// #include @@ -14,8 +13,6 @@ namespace XSC using Introspection::Access; // FundamentalType - // - // namespace { TypeInfo @@ -34,8 +31,6 @@ namespace XSC // AnyType - // - // namespace { TypeInfo @@ -55,8 +50,6 @@ namespace XSC // AnySimpleType - // - // namespace { TypeInfo @@ -76,8 +69,6 @@ namespace XSC // AnyUri - // - // namespace { TypeInfo any_uri_init_ () @@ -99,8 +90,6 @@ namespace XSC // DateTime - // - // namespace { TypeInfo @@ -118,8 +107,6 @@ namespace XSC static_type_info () { return date_time_; } // Byte - // - // namespace { TypeInfo @@ -139,8 +126,6 @@ namespace XSC // UnsignedByte - // - // namespace { TypeInfo @@ -160,8 +145,6 @@ namespace XSC // Short - // - // namespace { TypeInfo @@ -181,8 +164,6 @@ namespace XSC // UnsignedShort - // - // namespace { TypeInfo @@ -202,8 +183,6 @@ namespace XSC // Int - // - // namespace { TypeInfo @@ -223,8 +202,6 @@ namespace XSC // UnsignedInt - // - // namespace { TypeInfo @@ -244,8 +221,6 @@ namespace XSC // Long - // - // namespace { TypeInfo @@ -265,8 +240,6 @@ namespace XSC // UnsignedLong - // - // namespace { TypeInfo @@ -286,8 +259,6 @@ namespace XSC // Decimal - // - // namespace { TypeInfo @@ -307,8 +278,6 @@ namespace XSC // Integer - // - // namespace { TypeInfo @@ -328,8 +297,6 @@ namespace XSC // NonPositiveInteger - // - // namespace { TypeInfo @@ -349,8 +316,6 @@ namespace XSC // NonNegativeInteger - // - // namespace { TypeInfo @@ -370,8 +335,6 @@ namespace XSC // PositiveInteger - // - // namespace { TypeInfo @@ -391,8 +354,6 @@ namespace XSC // NegativeInteger - // - // namespace { TypeInfo @@ -412,8 +373,6 @@ namespace XSC // Boolean - // - // namespace { TypeInfo @@ -433,8 +392,6 @@ namespace XSC // Float - // - // namespace { TypeInfo @@ -454,8 +411,6 @@ namespace XSC // Double - // - // namespace { TypeInfo @@ -475,8 +430,6 @@ namespace XSC // String - // - // namespace { TypeInfo @@ -496,8 +449,6 @@ namespace XSC // NormalizedString - // - // namespace { TypeInfo @@ -517,8 +468,6 @@ namespace XSC // Token - // - // namespace { TypeInfo @@ -538,8 +487,6 @@ namespace XSC // Name - // - // namespace { TypeInfo @@ -559,8 +506,6 @@ namespace XSC // NMTOKEN - // - // namespace { TypeInfo @@ -580,8 +525,6 @@ namespace XSC // NCName - // - // namespace { TypeInfo @@ -601,8 +544,6 @@ namespace XSC // QName - // - // namespace { TypeInfo @@ -622,8 +563,6 @@ namespace XSC // Id - // - // namespace { TypeInfo @@ -643,8 +582,6 @@ namespace XSC // IdRef - // - // namespace { TypeInfo @@ -664,8 +601,6 @@ namespace XSC // Href - // - // namespace { TypeInfo diff --git a/XSC/SemanticGraph/Fundamental.hpp b/XSC/SemanticGraph/Fundamental.hpp index 8c32836..d126d63 100644 --- a/XSC/SemanticGraph/Fundamental.hpp +++ b/XSC/SemanticGraph/Fundamental.hpp @@ -2,7 +2,6 @@ // author : Boris Kolpackov // Note, that this file is automatically generated! -// #ifndef XSC_SEMANTIC_GRAPH_FUNDAMENTAL_HPP #define XSC_SEMANTIC_GRAPH_FUNDAMENTAL_HPP @@ -13,9 +12,6 @@ namespace XSC { namespace SemanticGraph { - // - // - // class FundamentalType : public virtual Type { public: @@ -30,9 +26,6 @@ namespace XSC }; - // - // - // class AnyType : public virtual FundamentalType { public: @@ -49,9 +42,6 @@ namespace XSC }; - // - // - // class AnySimpleType : public virtual FundamentalType { public: @@ -68,9 +58,6 @@ namespace XSC }; - // - // - // class AnyUri : public virtual FundamentalType { public: @@ -87,9 +74,6 @@ namespace XSC }; - // - // - // class DateTime : public virtual FundamentalType { public: @@ -106,9 +90,6 @@ namespace XSC }; - // - // - // class Byte : public virtual FundamentalType { public: @@ -125,9 +106,6 @@ namespace XSC }; - // - // - // class UnsignedByte : public virtual FundamentalType { public: @@ -144,9 +122,6 @@ namespace XSC }; - // - // - // class Short : public virtual FundamentalType { public: @@ -163,9 +138,6 @@ namespace XSC }; - // - // - // class UnsignedShort : public virtual FundamentalType { public: @@ -182,9 +154,6 @@ namespace XSC }; - // - // - // class Int : public virtual FundamentalType { public: @@ -201,9 +170,6 @@ namespace XSC }; - // - // - // class UnsignedInt : public virtual FundamentalType { public: @@ -220,9 +186,6 @@ namespace XSC }; - // - // - // class Long : public virtual FundamentalType { public: @@ -239,9 +202,6 @@ namespace XSC }; - // - // - // class UnsignedLong : public virtual FundamentalType { public: @@ -258,9 +218,6 @@ namespace XSC }; - // - // - // class Decimal : public virtual FundamentalType { public: @@ -277,9 +234,6 @@ namespace XSC }; - // - // - // class Integer : public virtual FundamentalType { public: @@ -296,9 +250,6 @@ namespace XSC }; - // - // - // class NonPositiveInteger : public virtual FundamentalType { public: @@ -315,9 +266,6 @@ namespace XSC }; - // - // - // class NonNegativeInteger : public virtual FundamentalType { public: @@ -334,9 +282,6 @@ namespace XSC }; - // - // - // class PositiveInteger : public virtual FundamentalType { public: @@ -353,9 +298,6 @@ namespace XSC }; - // - // - // class NegativeInteger : public virtual FundamentalType { public: @@ -372,9 +314,6 @@ namespace XSC }; - // - // - // class Boolean : public virtual FundamentalType { public: @@ -391,9 +330,6 @@ namespace XSC }; - // - // - // class Float : public virtual FundamentalType { public: @@ -410,9 +346,6 @@ namespace XSC }; - // - // - // class Double : public virtual FundamentalType { public: @@ -429,9 +362,6 @@ namespace XSC }; - // - // - // class String : public virtual FundamentalType { public: @@ -448,9 +378,6 @@ namespace XSC }; - // - // - // class NormalizedString : public virtual FundamentalType { public: @@ -467,9 +394,6 @@ namespace XSC }; - // - // - // class Token : public virtual FundamentalType { public: @@ -486,9 +410,6 @@ namespace XSC }; - // - // - // class Name : public virtual FundamentalType { public: @@ -505,9 +426,6 @@ namespace XSC }; - // - // - // class NMTOKEN : public virtual FundamentalType { public: @@ -524,9 +442,6 @@ namespace XSC }; - // - // - // class NCName : public virtual FundamentalType { public: @@ -543,9 +458,6 @@ namespace XSC }; - // - // - // class QName : public virtual FundamentalType { public: @@ -562,9 +474,6 @@ namespace XSC }; - // - // - // class Id : public virtual FundamentalType { public: @@ -581,9 +490,6 @@ namespace XSC }; - // - // - // class IdRef : public virtual FundamentalType { public: @@ -600,9 +506,6 @@ namespace XSC }; - // - // - // class Href : public virtual FundamentalType { public: diff --git a/XSC/SemanticGraph/Graph.tpp b/XSC/SemanticGraph/Graph.tpp index bead3a2..c121b8a 100644 --- a/XSC/SemanticGraph/Graph.tpp +++ b/XSC/SemanticGraph/Graph.tpp @@ -7,8 +7,6 @@ namespace XSC namespace SemanticGraph { // Graph - // - // template template @@ -63,12 +61,10 @@ namespace XSC { // One endpoint of the edge has removed this edge from // its edge set. Now handle the other endpoint. - // if (e->left_ () == n) e->right_ ()->remove_edge_ (e); else e->left_ ()->remove_edge_ (e); // Delete the edge. - // edges_.erase (e); delete e; //@@ auto diff --git a/XSC/SemanticGraph/Schema.cpp b/XSC/SemanticGraph/Schema.cpp index 1011254..af6d827 100644 --- a/XSC/SemanticGraph/Schema.cpp +++ b/XSC/SemanticGraph/Schema.cpp @@ -12,8 +12,6 @@ namespace XSC // Implies - // - // namespace { TypeInfo @@ -32,8 +30,6 @@ namespace XSC // Sources - // - // namespace { TypeInfo @@ -52,8 +48,6 @@ namespace XSC // Includes - // - // namespace { TypeInfo @@ -72,8 +66,6 @@ namespace XSC // Imports - // - // namespace { TypeInfo @@ -92,8 +84,6 @@ namespace XSC // Schema - // - // namespace { TypeInfo @@ -120,7 +110,6 @@ namespace XSC names_.clear (); // Check our own namespace first so it will end up first in the list. - // NamesIteratorPair pair (Scope::find (name)); names_.insert (names_.end (), pair.first, pair.second); diff --git a/XSC/SemanticGraph/Schema.hpp b/XSC/SemanticGraph/Schema.hpp index 57d9489..3edaf59 100644 --- a/XSC/SemanticGraph/Schema.hpp +++ b/XSC/SemanticGraph/Schema.hpp @@ -16,9 +16,6 @@ namespace XSC class Schema; - // - // - // class Implies : public virtual Contains { public: @@ -44,9 +41,6 @@ namespace XSC std::filesystem::path file_; }; - // - // - // class Sources : public virtual Contains { public: @@ -73,9 +67,6 @@ namespace XSC }; - // - // - // class Includes : public virtual Contains { public: @@ -102,9 +93,6 @@ namespace XSC }; - // - // - // class Imports : public virtual Contains { public: @@ -178,8 +166,8 @@ namespace XSC } private: - Schema (Schema const&); - void operator= (Schema const&); + Schema (Schema const&) = delete; + Schema& operator= (Schema const&) = delete; private: Contains* contained_ {}; diff --git a/XSC/Traversal/Attribute.cpp b/XSC/Traversal/Attribute.cpp index 369f47f..06a81be 100644 --- a/XSC/Traversal/Attribute.cpp +++ b/XSC/Traversal/Attribute.cpp @@ -8,8 +8,6 @@ namespace XSC namespace Traversal { // Attribute - // - // void Attribute:: traverse (Type& a) { diff --git a/XSC/Traversal/Attribute.hpp b/XSC/Traversal/Attribute.hpp index 9611f8d..a07b73b 100644 --- a/XSC/Traversal/Attribute.hpp +++ b/XSC/Traversal/Attribute.hpp @@ -11,9 +11,6 @@ namespace XSC { namespace Traversal { - // - // - // struct Attribute : Node { void diff --git a/XSC/Traversal/Elements.cpp b/XSC/Traversal/Elements.cpp index 4bd5673..8382739 100644 --- a/XSC/Traversal/Elements.cpp +++ b/XSC/Traversal/Elements.cpp @@ -8,8 +8,6 @@ namespace XSC namespace Traversal { // Instance - // - // void Instance:: traverse (Type& a) { diff --git a/XSC/Traversal/Elements.hpp b/XSC/Traversal/Elements.hpp index 0363575..3ba8f97 100644 --- a/XSC/Traversal/Elements.hpp +++ b/XSC/Traversal/Elements.hpp @@ -18,9 +18,6 @@ namespace XSC { namespace Traversal { - // - // - // template class Traverser { @@ -36,9 +33,6 @@ namespace XSC }; - // - // - // template class Dispatcher { @@ -102,16 +96,10 @@ namespace XSC }; - // - // - // using NodeDispatcherBase = Dispatcher; using EdgeDispatcherBase = Dispatcher; - // - // - // class NodeDispatcher : public virtual NodeDispatcherBase { public: @@ -119,15 +107,11 @@ namespace XSC edge_traverser (EdgeDispatcherBase& d) { //@@ this should be done in Dispatcher in merge() function? - // - for (EdgeDispatcherBase::Iterator i (d.begin ()), end (d.end ()); - i != end; ++i) + for (auto const& [type_id, traversers] : d) { - for (EdgeDispatcherBase::Traversers::const_iterator - t (i->second.begin ()), end (i->second.end ()); - t != end; ++t) + for (Traverser* traverser : traversers) { - dispatcher_.map (i->first, **t); + dispatcher_.map (type_id, *traverser); } } } @@ -175,18 +159,14 @@ namespace XSC { public: //@@ this should be done in Dispatcher in merge() function? - // void node_traverser (NodeDispatcherBase& d) { - for (NodeDispatcherBase::Iterator i (d.begin ()), end (d.end ()); - i != end; ++i) + for (auto const& [type_id, traversers] : d) { - for (NodeDispatcherBase::Traversers::const_iterator - t (i->second.begin ()), end (i->second.end ()); - t != end; ++t) + for (Traverser* traverser : traversers) { - dispatcher_.map (i->first, **t); + dispatcher_.map (type_id, *traverser); } } } @@ -203,9 +183,6 @@ namespace XSC }; - // - // - // template struct Node : Traverser, virtual NodeDispatcher { @@ -252,8 +229,6 @@ namespace XSC }; // Edges - // - // struct Names : Edge { void @@ -275,8 +250,6 @@ namespace XSC // Nodes - // - // struct Nameable : Node { }; @@ -332,15 +305,9 @@ namespace XSC }; - // - // - // using Scope = ScopeTemplate; - // - // - // struct Type : Node { void @@ -348,9 +315,6 @@ namespace XSC }; - // - // - // struct Instance : Node { void @@ -369,9 +333,6 @@ namespace XSC post (Type&); }; - // - // - // struct Inherits : Edge { void @@ -381,9 +342,6 @@ namespace XSC } }; - // - // - // struct Contains : Edge { void diff --git a/XSC/Traversal/Elements.tpp b/XSC/Traversal/Elements.tpp index 9a4132b..664230d 100644 --- a/XSC/Traversal/Elements.tpp +++ b/XSC/Traversal/Elements.tpp @@ -8,16 +8,12 @@ namespace XSC namespace Traversal { // Traverser - // - // template Traverser:: ~Traverser () = default; // Dispatcher - // - // template Dispatcher:: @@ -35,37 +31,30 @@ namespace XSC { TypeInfoSet dispatched; - for (typename LevelMap::const_iterator - i (levels.begin ()), e (levels.end ()); - i != e; ++i) + for (auto const& [type_info, level] : levels) { - if (i->second == l) + if (level == l) { typename TraversalMap::const_iterator v ( - traversal_map_.find (i->first.type_id ())); + traversal_map_.find (type_info.type_id ())); if (v != traversal_map_.end ()) { Traversers const& traversers (v->second); - for (typename Traversers::const_iterator - ti (traversers.begin ()), te (traversers.end ()); - ti != te; ++ti) + for (Traverser* traverser : traversers) { - (*ti)->trampoline (n); + traverser->trampoline (n); } - flatten_tree (i->first, dispatched); + flatten_tree (type_info, dispatched); } } } // Remove traversed types from level map. - // - for (typename TypeInfoSet::const_iterator i = dispatched.begin (); - i != dispatched.end (); - ++i) + for (Introspection::TypeInfo const& type_info : dispatched) { - levels.erase (*i); + levels.erase (type_info); } } } diff --git a/XSC/Traversal/Enumeration.cpp b/XSC/Traversal/Enumeration.cpp index c6676e7..f6f0612 100644 --- a/XSC/Traversal/Enumeration.cpp +++ b/XSC/Traversal/Enumeration.cpp @@ -8,8 +8,6 @@ namespace XSC namespace Traversal { // Enumeration - // - // void Enumeration:: traverse (Type& s) { @@ -36,8 +34,6 @@ namespace XSC // Enumerator - // - // void Enumerator:: traverse (Type& a) { diff --git a/XSC/Traversal/Schema.hpp b/XSC/Traversal/Schema.hpp index 69ff826..60ea3fd 100644 --- a/XSC/Traversal/Schema.hpp +++ b/XSC/Traversal/Schema.hpp @@ -11,9 +11,6 @@ namespace XSC { namespace Traversal { - // - // - // struct Implies : Edge { void @@ -23,9 +20,6 @@ namespace XSC } }; - // - // - // struct Sources : Edge { void @@ -36,9 +30,6 @@ namespace XSC }; - // - // - // struct Includes : Edge { void @@ -49,9 +40,6 @@ namespace XSC }; - // - // - // struct Imports : Edge { void @@ -62,9 +50,6 @@ namespace XSC }; - // - // - // struct Schema : ScopeTemplate { void diff --git a/XSC/be/CXX/Elements.cpp b/XSC/be/CXX/Elements.cpp index e460f3a..0d7c8a7 100644 --- a/XSC/be/CXX/Elements.cpp +++ b/XSC/be/CXX/Elements.cpp @@ -9,7 +9,6 @@ #include // Namespace -// string Context:: ns_name (SemanticGraph::Namespace& ns) @@ -55,7 +54,6 @@ ns_name (SemanticGraph::Namespace& ns) r = regex::perl_s (r, L"#/#::#"); // replace `/' with `::' // Check the result. - // if (regex::perl_s ( r, L"/^([a-zA-Z_]\\w*)(::[a-zA-Z_]\\w*)*$//").empty ()) break; } @@ -134,7 +132,6 @@ fq_name (SemanticGraph::Nameable& n, string const& nss, bool mangle) namespace { //@@ recode using Fundamental - // struct TypeName : protected virtual Context, Traversal::Type, /* @@ -326,12 +323,10 @@ namespace //@@ In what situations would I produce different name by // these two functions? -// string Context:: type_name (SemanticGraph::Type& t, string const& nss) { // There cannot be a named type inside an anonymous one. - // if (t.named ()) { string r; @@ -553,7 +548,6 @@ id (string const& name) // Namespace -// void Namespace:: pre (Type& n) { diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 7f23361..4918e88 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -20,7 +20,6 @@ using string = std::wstring; using NamespaceMapping = std::vector; -// class Context { public: @@ -152,23 +151,19 @@ class Context protected: // Escape C++ keywords. - // string id (string const& name); // Translate XML namespace name to C++ identifier. - // string ns_name (SemanticGraph::Namespace& ns); // Original schema namespace name. - // string xs_ns_name (SemanticGraph::Nameable& ns); // Mapping for fq-type-name. Takes into account current scope // for anonymous names. - // string type_name (SemanticGraph::Instance& i, string const& ns_suffix = L""); @@ -472,7 +467,6 @@ struct Anonymous : Traversal::Element, // Usual namespace mapping. -// struct Namespace : Traversal::Namespace, protected virtual Context { Namespace (Context& c) @@ -506,7 +500,6 @@ struct Traverser : T }; // Checks if scope `Y' names any of `X' -// template bool has (Y& y) @@ -646,7 +639,6 @@ has_constructor_optional_members (SemanticGraph::Complex& c) } // Fundamental type mapping helper. -// struct Fundamental : Traversal::FundamentalType, Traversal::String, Traversal::NormalizedString, diff --git a/XSC/be/CXX/Generator.cpp b/XSC/be/CXX/Generator.cpp index 878b380..e4926f4 100644 --- a/XSC/be/CXX/Generator.cpp +++ b/XSC/be/CXX/Generator.cpp @@ -148,7 +148,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con write_version (cxx); // Banner. - // //Takes in the name of a "banner" file. This banner, if it exists, will //be inserted at the head of the output files. { @@ -171,7 +170,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con } // header - // { std::string bn (options.value ("cxx-header-banner-file")); @@ -198,7 +196,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con } // inline - // if (inline_) { std::string bn (options.value ("cxx-inline-banner-file")); @@ -226,7 +223,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con } // source - // { std::string bn (options.value ("cxx-header-banner-file")); @@ -253,8 +249,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con } } - // - // string char_type; { @@ -266,7 +260,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con // Set auto-indentation. - // Indentation::Implanter hxx_guard (hxx); Indentation::Implanter ixx_guard (ixx); Indentation::Implanter cxx_guard (cxx); @@ -290,27 +283,23 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con NamespaceMapping nsm; // Default mapping. - // nsm.push_back (L"#^.* (.*?/)??" L"(([a-zA-Z_]\\w*)(/[a-zA-Z_]\\w*)*)$#$2#"); if (options.count ("cxx-namespace-regex")) { // Custom mappings. - // std::vector const& custom_nsm {options.values ("cxx-namespace-regex")}; - for (std::vector::const_iterator i = custom_nsm.begin (); - i != custom_nsm.end (); ++i) + for (std::string const& mapping : custom_nsm) { std::wostringstream o; - o << i->c_str (); + o << mapping.c_str (); nsm.push_back (o.str ()); } } // Export symbol - // string export_symbol; { std::wostringstream o; @@ -319,7 +308,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con } // HXX - // std::string guard (hxx_name); std::string guard_flag (options.value ("cxx-header-guard")); // When the userhas passed a special guard use that, else construct one @@ -330,19 +318,15 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con else { // Split words - // guard = regex::perl_s (guard, "/([a-z])([A-Z])/$1_$2/"); // Upcase. - // std::transform (guard.begin (), guard.end(), guard.begin (), upcase); // Replace '.' with '_'. - // guard = regex::perl_s (guard, "/\\./_/"); // Replace '-' with '_'. - // guard = regex::perl_s (guard, "/\\-/_/"); } @@ -406,7 +390,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con hxx << "#endif // " << guard.c_str () << std::endl; // IXX - // if (inline_) { ::Context ctx (ixx, char_type, export_symbol, nsm); @@ -427,7 +410,6 @@ generate (XSC::Options const& options, Schema& schema, std::filesystem::path con // CXX - // cxx << "#include \"" << hxx_name.c_str () << "\"" << std::endl << "#include " << std::endl << std::endl; diff --git a/XSC/be/CXX/Generator.hpp b/XSC/be/CXX/Generator.hpp index b3cf194..96c0126 100644 --- a/XSC/be/CXX/Generator.hpp +++ b/XSC/be/CXX/Generator.hpp @@ -33,7 +33,6 @@ #include //@@ SemanticGraphFwd could be useful here. -// #include "XSC/SemanticGraph.hpp" #include "XSC/Options.hpp" diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 5b103c0..c297595 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -40,8 +40,6 @@ namespace }; // List of all non-optional members - // - // struct CtorArgs : Traversal::Complex, protected Traversal::Enumeration, //protected Traversal::Type, @@ -246,7 +244,6 @@ namespace string accessor_name (sequence_accessor_name (c)); // sequence - // switch(this->cppmode_) { case CPPMODE::CPP03: @@ -332,7 +329,6 @@ namespace else if (c.min () == 0) { // optional - // if (!this->optional_via_if_set ()) { os << "bool " << name << "_p () const;"; @@ -382,7 +378,6 @@ namespace else { // one - // os << type << " const& " << id (name) << " () const;"; // os << type << "& " << id (name) << " ();"; // Lets just have one mutator. if (this->read_only_) @@ -685,7 +680,6 @@ namespace os << Indentation::unindent << "public:" << std::endl << Indentation::indent; // c-tor (all-non-optional-members) - // if (this->read_only_) { if (this->cppmode_ == CPPMODE::CPP03) @@ -716,11 +710,9 @@ namespace } // c-tor (Element const&) - // os << "explicit " << name << " (" << xml_element_type << " const&);"; // c-tor (Attribute const&) - // bool r (true); struct Traverser : Traversal::Inherits, @@ -756,7 +748,6 @@ namespace } // copy c-tor - // if (this->read_only_) { if (this->cppmode_ == CPPMODE::CPP03) @@ -789,7 +780,6 @@ namespace << (default_copy ? " = default;" : ";"); // operator= - // os << name << "& operator= (" << name << " const& s)" << (default_copy ? " = default;" : ";"); @@ -929,11 +919,9 @@ namespace } // c-tor (Element const&) - // os << "explicit " << name << " (" << xml_element_type << " const&);"; // c-tor (Attribute const&) - // os << "explicit " << name << " (" << xml_attribute_type << " const&);"; os << std::endl; diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 102f45c..71febb8 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -47,7 +47,6 @@ namespace if (e.min () == 0 && e.max () == 1) { // optional - // if (this->optional_via_if_set ()) { string noexcept_suffix (this->cppmode_ == CPPMODE::CPP03 ? L"" : L" noexcept"); @@ -138,7 +137,6 @@ namespace else if (e.min () == 1 && e.max () == 1) { // one - // os << i << type << " const& " << scope << "::" << id (name) << " () const" << "{" @@ -175,7 +173,6 @@ namespace else { // sequence - // string accessor_name (sequence_accessor_name (e)); @@ -195,7 +192,6 @@ namespace if (!this->read_only_) { // begin_typename - // os << i << scope << "::" << name << "_iterator " << scope << "::begin_" << name << " ()" << "{" @@ -203,7 +199,6 @@ namespace << "}"; // end_typename - // os << i << scope << "::" << name << "_iterator " << scope << "::end_" << name << " ()" << "{" @@ -273,7 +268,6 @@ namespace if (this->cppmode_ != CPPMODE::CPP17) { // count_typename - // os << i << "size_t " << scope << "::count_" << name << "() const" << (this->cppmode_ == CPPMODE::CPP17 ? " noexcept" : "") @@ -437,7 +431,6 @@ namespace // List of all non-optional members // @@ this code is the same as in Header.cpp - // struct CtorArgs : Traversal::Complex, protected Traversal::Enumeration, //protected Traversal::Type, @@ -608,7 +601,6 @@ namespace if (!default_constructor) { // c-tor - // os << i << scope << "::" << name << " ("; @@ -639,7 +631,6 @@ namespace if (!default_copy) { // copy c-tor - // os << i << scope << "::" << name << " (" << type << " const& s)" << std::endl; @@ -677,7 +668,6 @@ namespace if (!this->read_only_) { // operator= - // os << i << scope << "& " << scope << "::operator= (" << type << " const& s)" << "{" @@ -916,7 +906,6 @@ namespace else if (e.min () == 1 && e.max () == 1) { // one - // string name (id (e.name ())); string type (type_name (e)); @@ -1002,7 +991,6 @@ namespace if (e.min () == 1 && e.max () == 1 && (this->cppmode_ == CPPMODE::CPP03)) { // one - // os << id (e.name ()) << "_->container (this);"; } } @@ -1065,7 +1053,6 @@ namespace if (e.min () == 0 && e.max () == 1) { // optional - // if (this->cppmode_ != CPPMODE::CPP03) { os << ", " << name << "_ (" @@ -1082,7 +1069,6 @@ namespace else if (e.min () == 1 && e.max () == 1) { // one - // if (this->cppmode_ != CPPMODE::CPP03) { os << ", " << name << "_ (std::make_unique<" << type << "> (*s." << name << "_))" << std::endl; @@ -1095,7 +1081,6 @@ namespace else { // sequence - // os << ", " << name << "_ (s." << name << "_)" << std::endl; } @@ -1172,7 +1157,6 @@ namespace name = id (name); // optional - // if (this->cppmode_ == CPPMODE::CPP03) { os << "if (" << name << "_.get ()) " @@ -1193,7 +1177,6 @@ namespace if (a.optional ()) { // optional - // if (this->cppmode_ == CPPMODE::CPP03) { os << "if (" << name << "_.get ()) " @@ -1237,7 +1220,6 @@ namespace name = id (name); // optional - // if (this->cppmode_ != CPPMODE::CPP03) { os << "if (s." << name << "_)" << std::endl @@ -1260,7 +1242,6 @@ namespace name = id (name); // one - // os << name << " (*s." << name << "_);" << std::endl; @@ -1268,7 +1249,6 @@ namespace else { // sequence - // os << id(name) << "_ = s." << id(name) << "_;" << std::endl; } diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 1fbf101..f01d511 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -44,7 +44,6 @@ namespace string char_type (this->char_type); //@@ can I get rid of the temporary? - // string compare_name; if (char_type == L"wchar_t") { @@ -60,7 +59,6 @@ namespace } //@@ need to use FQ-names. - // os << (first_ ? "if (n == " : "else if (n == ") << compare_name << ")" << "{"; @@ -69,7 +67,6 @@ namespace if (c.max () != 1) { // sequence - // if (this->cppmode_ != CPPMODE::CPP03) { os << id (name) << "_.emplace_back (e);"; @@ -87,7 +84,6 @@ namespace else if (c.min () == 0) { // optional - // if (this->read_only_) { if (this->cppmode_ != CPPMODE::CPP03) @@ -104,7 +100,6 @@ namespace else { // one - // if (this->cppmode_ != CPPMODE::CPP03) { os << id (name) << "_ = std::make_unique<" << type << "> (e);"; @@ -242,7 +237,6 @@ namespace string type (type_name (a)); //@@ need to use FQ-names. - // os << (first_ ? "if (n == " : "else if (n == ") << string_literal (name) << ")" << "{"; @@ -495,14 +489,12 @@ namespace else if (e.min () == 0) { // optional - // this->optional_element_list_.push_back (&e); } else { name = id (name); - // // one os << "// " << name << std::endl; @@ -538,7 +530,6 @@ namespace name = id (name); // optional - // os << " // " << name << std::endl; if (!this->optional_via_if_set ()) { @@ -577,7 +568,6 @@ namespace } else { - // // one // check if the type is a boolean type @@ -611,16 +601,16 @@ namespace // Write the sequence elements if (! this->complex_list_.empty ()) { - for (size_t i =0; i < this->complex_list_.size (); i++) - this->write_sequence (*this->complex_list_[i]); + for (SemanticGraph::Element* element : this->complex_list_) + this->write_sequence (*element); // Write Optional elements AFTER sequence elements if (! this->optional_element_list_.empty ()) { - for (size_t i=0; i < this->optional_element_list_.size (); i++) + for (SemanticGraph::Element* element : this->optional_element_list_) { - string name (this->optional_element_list_[i]->name ()); - string type (type_name (*this->optional_element_list_[i])); + string name (element->name ()); + string type (type_name (*element)); os << "// " << name << std::endl; @@ -892,14 +882,12 @@ namespace // Case 1: Type is a new type that is defined // in the schema. Then all we need to // is directly read in the value. - // // Case 2: Type is a simple type, i.e., it // does not have >> and << generated. // Case 2.1: Type inherits from a type that // has to be read as a pointer // Case 2.2: Type inherits from a type that // has to be read as a value directly. - // string type (type_name (e)); string name (e.name ()); @@ -1091,10 +1079,11 @@ namespace string type (type_name (c)); os << "element = new " << type << " ("; - for (size_t i =0; i < this->type_name_list_.size (); i++) + bool first (true); + for (string const& type_name : this->type_name_list_) { - os << (i? ", " : "") - << this->type_name_list_[i]; + os << (first ? "" : ", ") << type_name; + first = false; } os << ");" << std::endl; @@ -1146,7 +1135,7 @@ namespace } void - pretty_print_optional_attribute (string &name) + pretty_print_optional_attribute (string const& name) { // Check if the first character is a "*" // Indicates the type is a pointer type @@ -1181,24 +1170,22 @@ namespace // Add optional attributes to the element if (! this->optional_attribute_list_.empty ()) { - for (size_t j =0; - j < this->optional_attribute_list_.size (); - j++) - pretty_print_optional_attribute (this->optional_attribute_list_[j]); + for (string const& attribute : this->optional_attribute_list_) + pretty_print_optional_attribute (attribute); os << std::endl; } // Write the sequence elements if (! this->complex_list_.empty ()) - for (size_t i =0; i < this->complex_list_.size (); i++) - this->read_sequence (*this->complex_list_[i]); + for (SemanticGraph::Element* element : this->complex_list_) + this->read_sequence (*element); // NOTE: The optional elements ALWAYS have to be read at // the END. if (! this->optional_element_list_.empty ()) - for (size_t i = 0; i < this->optional_element_list_.size (); i++) + for (SemanticGraph::Element* element : this->optional_element_list_) { - string name (this->optional_element_list_[i]->name ()); + string name (element->name ()); // Read the optional part first os << "bool " << name << "_p;" << "stream.read_boolean (" << name << "_p);"; @@ -1207,7 +1194,7 @@ namespace << "{"; // The element is optional - read_generic_type (*this->optional_element_list_[i], 1); + read_generic_type (*element, 1); // Add that type to the element os << "element->" << name << " (" << name << ");" @@ -1256,7 +1243,6 @@ namespace //@@ I am using this traverser to handle anonymous types which is // not very clean (and asymmetric). - // struct ComplexElement : Traversal::Complex, protected virtual Context { ComplexElement (Context& c, @@ -1290,7 +1276,6 @@ namespace c.context ().set ("name", name); // Go after anonymous types first. - // names (c, names_anonymous_); Traversal::Complex::traverse (c); @@ -1595,7 +1580,6 @@ namespace enter_scope (name); // c-tor (Element const&) - // os << scope << "::" << name << " (" << xml_element_type << " const& e)" << std::endl << ": ::XSCRT::Type (e)" << std::endl << "{" @@ -1610,7 +1594,6 @@ namespace os << "}"; // c-tor (Attribute const&) - // os << scope << "::" << name << " (" << xml_attribute_type << " const& a)" << std::endl << ": ::XSCRT::Type (a)" << std::endl << "{" diff --git a/XSC/be/CXX/TraversalHeader.cpp b/XSC/be/CXX/TraversalHeader.cpp index 3d25a25..95853dc 100644 --- a/XSC/be/CXX/TraversalHeader.cpp +++ b/XSC/be/CXX/TraversalHeader.cpp @@ -36,7 +36,6 @@ namespace traverse (SemanticGraph::Element& e) { // Anonymous types cannot be traversed. - // //if (!e.type ().named ()) // return; @@ -45,34 +44,28 @@ namespace if (e.max () != 1) { // sequence - // // name - // declaration (id (name), L"Type&"); declaration (id (name), L"Type const&"); // name_pre - // declaration (name + L"_pre", L"Type&"); declaration (name + L"_pre", L"Type const&"); // name_next - // declaration (name + L"_next", L"Type&"); declaration (name + L"_next", L"Type const&"); // name_post - // declaration (name + L"_post", L"Type&"); declaration (name + L"_post", L"Type const&"); // name_none - // if (e.min () == 0) { declaration (name + L"_none", L"Type&"); @@ -82,15 +75,12 @@ namespace else if (e.min () == 0) { // optional - // // name - // declaration (id (name), L"Type&"); declaration (id (name), L"Type const&"); // name_none - // declaration (name + L"_none", L"Type&"); declaration (name + L"_none", L"Type const&"); @@ -98,10 +88,8 @@ namespace else { // one - // // name - // declaration (id (name), L"Type&"); declaration (id (name), L"Type const&"); } @@ -112,7 +100,6 @@ namespace traverse (SemanticGraph::Attribute& a) { // Anonymous types cannot be traversed. - // if (!a.type ().named ()) return; string name (a.name ()); @@ -121,19 +108,16 @@ namespace if (a.optional ()) { // name - // declaration (id (name), L"Type&"); declaration (id (name), L"Type const&"); // name_none - // declaration (name + L"_none", L"Type&"); declaration (name + L"_none", L"Type const&"); } else { // name - // declaration (id (name), L"Type&"); declaration (id (name), L"Type const&"); } @@ -217,14 +201,12 @@ namespace << "{"; // traverse () - // os << virtual_string << "void traverse (Type&)" << override_string << ";" << std::endl; os << virtual_string << "void traverse (Type const&)" << override_string << ";" << std::endl; // pre () - // os << "virtual void pre (Type&);" << std::endl; os << "virtual void pre (Type const&);" << std::endl; } @@ -233,7 +215,6 @@ namespace post (Type& ) { // post () - // os << "virtual void post (Type&);" << std::endl; os << "virtual void post (Type const&);" << std::endl; diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index 3bf3f35..f6be3c7 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -62,7 +62,6 @@ namespace traverse (SemanticGraph::Element& e) { // Anonymous types cannot be traversed. - // //if (!e.type ().named ()) //return; @@ -73,14 +72,11 @@ namespace if (e.min () == 0 && e.max () == 1) { // optional - // // name - // optional_member (name, type); // name_none - // os << "void " << scope << "::" << name << "_none (Type&)" << "{" @@ -94,10 +90,8 @@ namespace else if (e.min () == 1 && e.max () == 1) { // one - // // name - // os << "void " << scope << "::" << id (name) << " (Type& o)" << "{dispatch (o." << id (name) << " ());}"; @@ -109,12 +103,10 @@ namespace else { // sequence - // string accessor_name (sequence_accessor_name (e)); // name - // string iterator_type (fq_name (e, L"", false)); iterator_type += this->read_only_ ? L"_const_iterator" : L"_iterator"; @@ -185,7 +177,6 @@ namespace // name_pre - // os << "void " << scope << "::" << name << "_pre (Type&)" << "{" @@ -198,7 +189,6 @@ namespace // name_next - // os << "void " << scope << "::" << name << "_next (Type&)" << "{" @@ -211,7 +201,6 @@ namespace // name_post - // os << "void " << scope << "::" << name << "_post (Type&)" << "{" @@ -223,7 +212,6 @@ namespace << "}"; // name_none - // if (e.min () == 0) { os << "void " << scope << "::" @@ -244,7 +232,6 @@ namespace traverse (SemanticGraph::Attribute& a) { // Anonymous types cannot be traversed. - // //if (!a.type ().named ()) // return; @@ -254,11 +241,9 @@ namespace if (a.optional ()) { // name - // optional_member (name, type_name (a)); // name_none - // os << "void " << scope << "::" << name << "_none (Type&)" << "{" @@ -272,7 +257,6 @@ namespace else { // name - // os << "void " << scope << "::" << id (name) << " (Type& o)" << "{" @@ -324,7 +308,6 @@ namespace traverse (SemanticGraph::Element& e) { // Anonymous types cannot be traversed. - // //if (!e.type ().named ()) return; string name (e.name ()); @@ -332,7 +315,6 @@ namespace if (e.min () == 0 && e.max () == 1) { // optional - // if (!this->optional_via_if_set ()) os << "if (o." << name << "_p ()) " << id (name) << " (o);" << "else " << name << "_none (o);"; @@ -345,13 +327,11 @@ namespace else if (e.min () == 1 && e.max () == 1) { // one - // os << id (name) << " (o);"; } else { // sequence - // os << id (name) << " (o);"; } } @@ -360,7 +340,6 @@ namespace traverse (SemanticGraph::Attribute& a) { // Anonymous types cannot be traversed. - // //if (!a.type ().named ()) return; string name (a.name ()); @@ -368,7 +347,6 @@ namespace if (a.optional ()) { // optional - // if (!this->optional_via_if_set ()) os << "if (o." << name << "_p ()) " << id (name) << " (o);" << "else " << name << "_none (o);"; @@ -381,7 +359,6 @@ namespace else { // one - // os << id (name) << " (o);"; } } @@ -444,7 +421,6 @@ namespace c.context ().set ("name", name_); // Go after anonymous types first. - // names (c, names_anonymous_); Traversal::Complex::traverse (c); @@ -463,7 +439,6 @@ namespace //enter_scope (name); // traverse (Type&) - // os << "void " << scope << "::" << "traverse (Type& o)" << "{" @@ -476,7 +451,6 @@ namespace << "}"; // traverse (Type const&) - // os << "void " << scope << "::" << "traverse (Type const& o)" << "{" @@ -490,7 +464,6 @@ namespace // pre () - // os << "void " << scope << "::" << "pre (Type&)" << "{" @@ -508,7 +481,6 @@ namespace // string name (id (name_)); // post () - // os << "void " << scope << "::" << "post (Type&)" << "{" diff --git a/XSC/be/CXX/TypeInfoSource.cpp b/XSC/be/CXX/TypeInfoSource.cpp index 18c6bb6..9bf2b6c 100644 --- a/XSC/be/CXX/TypeInfoSource.cpp +++ b/XSC/be/CXX/TypeInfoSource.cpp @@ -67,7 +67,6 @@ namespace pre (Type& c) { //@@ cache name as a member? - // os << "struct " << name_ << "TypeInfoInitializer" << "{" @@ -94,7 +93,6 @@ namespace << "}"; // Go after anonymous types. - // names (c, names_anonymous_); os << "};" diff --git a/XSC/be/CXX/Validator.cpp b/XSC/be/CXX/Validator.cpp index d516de9..70ef9f8 100644 --- a/XSC/be/CXX/Validator.cpp +++ b/XSC/be/CXX/Validator.cpp @@ -12,7 +12,6 @@ namespace { //@! Inheriting from Context is just wrong! - // class ValidationContext : public Context { public: @@ -103,7 +102,6 @@ namespace traverse (static_cast (c)); //@@ maybe use traverser? - // SemanticGraph::Complex::InheritsIterator it (c.inherits_begin ()); if (it != c.inherits_end ()) diff --git a/XSC/be/CXX/WriterHeader.cpp b/XSC/be/CXX/WriterHeader.cpp index c5e66b0..778dc5c 100644 --- a/XSC/be/CXX/WriterHeader.cpp +++ b/XSC/be/CXX/WriterHeader.cpp @@ -31,7 +31,6 @@ namespace traverse (SemanticGraph::Element& e) { // Anonymous types cannot be traversed. - // //if (!e.type ().named ()) // return; @@ -51,7 +50,6 @@ namespace } // optional - // os << "virtual void" << std::endl << id (name) << " (Type const&);" << std::endl; @@ -70,7 +68,6 @@ namespace } // one - // os << "virtual void" << std::endl << id (name) << " (Type const&);" << std::endl; @@ -78,10 +75,8 @@ namespace else { // sequence - // // Pre - // if (this->cppmode_ == CPPMODE::CPP03) { os << "virtual void" << std::endl @@ -93,13 +88,11 @@ namespace } // pre - // os << "virtual void" << std::endl << name << "_pre (Type const&);" << std::endl; // non-const next - // if (this->cppmode_ == CPPMODE::CPP03) { os << "virtual void" << std::endl @@ -111,7 +104,6 @@ namespace } // next - // os << "virtual void" << std::endl << name << "_next (Type const&);" << std::endl; @@ -128,7 +120,6 @@ namespace } // post - // os << "virtual void" << std::endl << name << "_post (Type const&);" << std::endl; @@ -139,7 +130,6 @@ namespace traverse (SemanticGraph::Attribute& a) { // Anonymous types cannot be traversed. - // //if (!a.type ().named ()) //return; @@ -254,7 +244,6 @@ namespace << "{"; //@@ Should probably be Type__ - // if (this->cppmode_ != CPPMODE::CPP03) { os << "using Type =" << fq_name (c) << ";"; @@ -265,7 +254,6 @@ namespace } // c-tor - // os << "explicit " << name_ << " (" << xml_element_type << "&);" << std::endl; @@ -284,7 +272,6 @@ namespace string override_string (this->cppmode_ != CPPMODE::CPP03 ? L" override" : L""); // traverse - // os << virtual_string << "void" << std::endl << "traverse (Type const&)" << override_string << ";" << std::endl; @@ -335,7 +322,6 @@ namespace << "{"; // c-tor - // os << "explicit " << name << " (" << xml_element_type << "&);" << std::endl; @@ -351,7 +337,6 @@ namespace } // traverse - // os << virtual_string << "void" << std::endl << "traverse (Type const&)" << override_string << ";" << std::endl; diff --git a/XSC/be/CXX/WriterSource.cpp b/XSC/be/CXX/WriterSource.cpp index 9cd7b23..adc616d 100644 --- a/XSC/be/CXX/WriterSource.cpp +++ b/XSC/be/CXX/WriterSource.cpp @@ -30,7 +30,6 @@ namespace traverse (SemanticGraph::Element& e) { // Anonymous types cannot be traversed. - // //if (!e.type ().named ()) // return; @@ -43,10 +42,8 @@ namespace if (e.max () != 1) { // sequence - // // pre - // os << "void " << scope << "::" << name << "_pre (Type const&)" << "{" @@ -57,7 +54,6 @@ namespace << "}"; // next - // os << "void " << scope << "::" << name << "_next (Type const& o)" << "{" @@ -67,7 +63,6 @@ namespace // post - // os << "void " << scope << "::" << name << "_post (Type const&)" << "{" @@ -77,7 +72,6 @@ namespace else { // optional & one - // os << "void " << scope << "::" << id (name) << " (Type const& o)" << "{" @@ -95,7 +89,6 @@ namespace traverse (SemanticGraph::Attribute& a) { // Anonymous types cannot be traversed. - // //if (!a.type ().named ()) // return; @@ -213,7 +206,6 @@ namespace c.context ().set ("name", name_); // Go after anonymous types first. - // names (c, names_anonymous_); Traversal::Complex::traverse (c); @@ -230,7 +222,6 @@ namespace string name (id (name_)); // c-tor (XML::Element&) - // os << scope << "::" << name << " (" << xml_element_type << "& e)" << std::endl << ": ::XSCRT::Writer<" << char_type << "> (e)" << std::endl @@ -238,7 +229,6 @@ namespace << "}"; // c-tor () - // if (this->cppmode_ == CPPMODE::CPP03) { os << scope << "::" @@ -248,7 +238,6 @@ namespace } // traverse - // os << "void " << scope << "::" << "traverse (Type const& o)" << "{"; @@ -309,7 +298,6 @@ namespace string name ((this->name_ != L"") ? id(name_) : id (c.name ())); // c-tor (XML::Element&) - // os << name << "::" << name << " (" << xml_element_type << "& e)" << std::endl << ": ::XSCRT::Writer<" << char_type << "> (e)" << std::endl @@ -317,7 +305,6 @@ namespace << "}"; // c-tor () - // if (this->cppmode_ == CPPMODE::CPP03) { os << name << "::" @@ -327,7 +314,6 @@ namespace } // traverse - // os << "void " << name << "::" << "traverse (Type const& o)" << "{" @@ -384,9 +370,6 @@ namespace } }; - // - // - // struct WriterBase : /*Traversal::Type, */ Fundamental, Traversal::Complex, @@ -531,7 +514,6 @@ namespace SemanticGraph::Type& t (c.type ()); //@@ need to use FQ-names. - // os << "namespace writer" << "{" << "void" << std::endl diff --git a/XSC/be/IDL/Definition.cpp b/XSC/be/IDL/Definition.cpp index 1f5f4a0..40a43b8 100644 --- a/XSC/be/IDL/Definition.cpp +++ b/XSC/be/IDL/Definition.cpp @@ -73,7 +73,6 @@ namespace string name_seq (id (name + L"_seq")); // sequence - // os << "typedef sequence< " << type << " > " << name_seq << ";" << "public " << name_seq << " " << id (name) << ";"; @@ -81,14 +80,12 @@ namespace else if (c.min () == 0) { // optional - // os << "boolean " << name << "_p ();" << "public " << type << " " << id (name) << ";"; } else { // one - // os << "public " << type << " " << id (name) << ";"; } diff --git a/XSC/be/IDL/Elements.cpp b/XSC/be/IDL/Elements.cpp index ee63d05..000fc5f 100644 --- a/XSC/be/IDL/Elements.cpp +++ b/XSC/be/IDL/Elements.cpp @@ -11,8 +11,6 @@ namespace IDL { // Namespace - // - // string Context:: ns_name (SemanticGraph::Namespace& ns) @@ -53,7 +51,6 @@ namespace IDL r = regex::perl_s (r, L"#/#::#"); // replace `/' with `::' // Check the result. - // if (regex::perl_s ( r, L"/^([a-zA-Z_]\\w*)(::[a-zA-Z_]\\w*)*$//").empty ()) break; } @@ -110,7 +107,6 @@ namespace IDL namespace { //@@ recode using Fundamental - // struct TypeName : protected virtual Context, Traversal::Type /* @@ -280,12 +276,10 @@ namespace IDL //@@ In what situations would I produce different name by // these two functions? - // string Context:: type_name (SemanticGraph::Type& t, string const& suffix) { // There cannot be a named type inside an anonymous one. - // if (t.named ()) { string r; @@ -452,8 +446,6 @@ namespace IDL // Namespace - // - // void Namespace:: pre (Type& n) { diff --git a/XSC/be/IDL/Elements.hpp b/XSC/be/IDL/Elements.hpp index faa8600..03d120a 100644 --- a/XSC/be/IDL/Elements.hpp +++ b/XSC/be/IDL/Elements.hpp @@ -18,8 +18,6 @@ namespace IDL using string = std::wstring; - // - // class Context { public: @@ -111,23 +109,19 @@ namespace IDL protected: // Escape C++ keywords. - // string id (string const& name); // Translate XML namespace name to C++ identifier. - // string ns_name (SemanticGraph::Namespace& ns); // Original schema namespace name. - // string xs_ns_name (SemanticGraph::Nameable& ns); // Mapping for fq-type-name. Takes into account current scope // for anonymous names. - // string type_name (SemanticGraph::Instance& i, string const& suffix = L""); @@ -229,7 +223,6 @@ namespace IDL // Usual namespace mapping. - // struct Namespace : Traversal::Namespace, protected virtual Context { Namespace (Context& c) @@ -246,7 +239,6 @@ namespace IDL // Checks if scope `Y' names any of `X' - // template bool has (Y& y) @@ -281,7 +273,6 @@ namespace IDL } // Fundamental type mapping helper. - // struct Fundamental : Traversal::FundamentalType, Traversal::String, Traversal::NormalizedString, diff --git a/XSC/be/IDL/Generator.cpp b/XSC/be/IDL/Generator.cpp index f51425a..3dc7654 100644 --- a/XSC/be/IDL/Generator.cpp +++ b/XSC/be/IDL/Generator.cpp @@ -24,7 +24,6 @@ namespace IDL { // On some platforms std::toupper can be something other than a // function with C++ linkage. - // int upcase (int c) { @@ -67,7 +66,6 @@ namespace IDL idl << std::endl; // Banner. - // { using namespace std; @@ -89,8 +87,6 @@ namespace IDL } } - // - // string char_type; { @@ -101,7 +97,6 @@ namespace IDL } // Set auto-indentation. - // Indentation::Implanter idl_guard (idl); @@ -111,17 +106,15 @@ namespace IDL nsm.push_back (L"#^.* (.*?/)??" L"(([a-zA-Z_]\\w*)(/[a-zA-Z_]\\w*)*)$#$2#"); // Custom mappings. - // if (options.count ("idl-namespace-regex")) { std::vector const& custom_nsm {options.values ("idl-namespace-regex")}; - for (std::vector::const_iterator i = custom_nsm.begin (); - i != custom_nsm.end (); ++i) + for (std::string const& mapping : custom_nsm) { std::wostringstream o; - o << i->c_str (); + o << mapping.c_str (); nsm.push_back (o.str ()); } } @@ -129,15 +122,12 @@ namespace IDL std::string guard (out_name); // Split words - // guard = regex::perl_s (guard, "/([a-z])([A-Z])/$1_$2/"); // Upcase. - // std::transform (guard.begin (), guard.end(), guard.begin (), upcase); // Replace '.' with '_'. - // guard = regex::perl_s (guard, "/\\./_/"); diff --git a/XSC/be/IDL/Generator.hpp b/XSC/be/IDL/Generator.hpp index 71ee6eb..7ce8610 100644 --- a/XSC/be/IDL/Generator.hpp +++ b/XSC/be/IDL/Generator.hpp @@ -7,7 +7,6 @@ #include //@@ SemanticGraphFwd could be useful here. -// #include "XSC/SemanticGraph.hpp" #include "XSC/Options.hpp" diff --git a/XSC/xsc.cpp b/XSC/xsc.cpp index d6786d9..a85e117 100644 --- a/XSC/xsc.cpp +++ b/XSC/xsc.cpp @@ -211,9 +211,7 @@ namespace } -// // main -// int main (int argc, char* argv[]) { try @@ -339,7 +337,6 @@ int main (int argc, char* argv[]) // This is a little hack to make XSC signal error conditions // by return value. Once I redesign diagnostic in CCF this should // be removed. - // ErrorDetector detector (std::wcerr); //"tu" is set to the schema path provided in the command line. @@ -360,7 +357,6 @@ int main (int argc, char* argv[]) { // Let C++ mapping evaluate the graph for possibility of generating // something useful. - // if (!CXX::validate (*s)) { return 1; From d871047ee839e99cf3431dcb81d5f65bfbca3d38 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 13:44:20 +0100 Subject: [PATCH 22/30] Modernize XSC code and cardinality accessors --- .../Utility/Introspection/TypeInfo.ipp | 2 +- XSC/Parser.cpp | 58 +++--- XSC/Parser.hpp | 22 +-- XSC/SemanticGraph/Element.hpp | 4 +- XSC/be/CXX/Elements.hpp | 6 +- XSC/be/CXX/Header.cpp | 57 +++--- XSC/be/CXX/Inline.cpp | 70 +++---- XSC/be/CXX/ParserHeader.cpp | 4 +- XSC/be/CXX/ParserSource.cpp | 4 +- XSC/be/CXX/Source.cpp | 176 ++++++++---------- XSC/be/CXX/TraversalHeader.cpp | 55 +++--- XSC/be/CXX/TraversalSource.cpp | 63 +++---- XSC/be/CXX/TypeInfoSource.cpp | 36 ++-- XSC/be/CXX/Validator.cpp | 16 +- XSC/be/CXX/WriterHeader.cpp | 61 +++--- XSC/be/CXX/WriterSource.cpp | 75 ++++---- XSC/be/IDL/Declaration.cpp | 2 +- XSC/be/IDL/Definition.cpp | 14 +- XSC/be/IDL/Elements.hpp | 4 +- 19 files changed, 322 insertions(+), 407 deletions(-) diff --git a/CCF/utility/Utility/Introspection/TypeInfo.ipp b/CCF/utility/Utility/Introspection/TypeInfo.ipp index 24d1aae..5d69cf1 100644 --- a/CCF/utility/Utility/Introspection/TypeInfo.ipp +++ b/CCF/utility/Utility/Introspection/TypeInfo.ipp @@ -70,7 +70,7 @@ namespace Utility inline void TypeInfo:: add_base (Access::Value access, bool virtual_base, TypeInfo const& ti) { - base_.push_back (BaseInfo (access, virtual_base, ti)); + base_.emplace_back (access, virtual_base, ti); } } } diff --git a/XSC/Parser.cpp b/XSC/Parser.cpp index b3986f4..7dc1ddf 100644 --- a/XSC/Parser.cpp +++ b/XSC/Parser.cpp @@ -17,14 +17,6 @@ #include #include -#if defined (min) -#undef min -#endif - -#if defined (max) -#undef max -#endif - namespace XSC { @@ -175,8 +167,8 @@ namespace XSC { Element& prot (dynamic_cast ((*i)->named ())); - Element& e (schema_.new_node (grp_min == 0 ? grp_min : prot.min (), - grp_max == 0 ? grp_max : prot.max (), + Element& e (schema_.new_node (grp_min == 0 ? grp_min : prot.minimum (), + grp_max == 0 ? grp_max : prot.maximum (), prot.qualified ())); schema_.new_edge (c, e, prot.name ()); @@ -601,10 +593,10 @@ namespace XSC //@@ min/max // min/max can come from element in the group! - unsigned long min (g[L"minOccurs"] == L"0" ? 0 : this->min ()), - max (g[L"maxOccurs"] && g[L"maxOccurs"] != L"1" ? 0 : this->max ()); + unsigned long minimum (g[L"minOccurs"] == L"0" ? 0 : this->minimum ()), + maximum (g[L"maxOccurs"] && g[L"maxOccurs"] != L"1" ? 0 : this->maximum ()); - if (trace_) std::wcout << "group min " << min << " max " << max << std::endl; + if (trace_) std::wcout << "group min " << minimum << " max " << maximum << std::endl; try @@ -616,8 +608,8 @@ namespace XSC { Element& prot (dynamic_cast ((*i)->named ())); - Element& e (root_schema_->new_node (min == 0 ? min : prot.min (), - max == 0 ? max : prot.max (), + Element& e (root_schema_->new_node (minimum == 0 ? minimum : prot.minimum (), + maximum == 0 ? maximum : prot.maximum (), prot.qualified ())); root_schema_->new_edge (scope (), e, prot.name ()); @@ -670,8 +662,8 @@ namespace XSC scope ().context ().set ("group-ns-name", ns_name); scope ().context ().set ("group-uq-name", uq_name); - scope ().context ().set ("group-min", min); - scope ().context ().set ("group-max", max); + scope ().context ().set ("group-min", minimum); + scope ().context ().set ("group-max", maximum); /* @@ This is too tricky for current stage of implementation. @@ -740,7 +732,7 @@ namespace XSC annotation (); - bool enum_ (false); + bool enum_ {}; if (more ()) { @@ -943,20 +935,20 @@ namespace XSC { if (c[L"maxOccurs"] == L"unbounded") { - push_cardinality (0, std::numeric_limits ::max ()); + push_cardinality (0, (std::numeric_limits ::max) ()); } else { string value (c[L"maxOccurs"]); std::wistringstream istr (value); - unsigned long max; - istr >> max; - push_cardinality (0, max); + unsigned long maximum; + istr >> maximum; + push_cardinality (0, maximum); } } else push_cardinality (0, - c[L"maxOccurs"] && c[L"maxOccurs"] != L"1" ? 0 : max ()); + c[L"maxOccurs"] && c[L"maxOccurs"] != L"1" ? 0 : maximum ()); if (c[L"maxOccurs"] && c[L"maxOccurs"] != L"1") { @@ -993,8 +985,8 @@ namespace XSC sequence (XML::Element const& s) { // Establish cardinality. - push_cardinality (s[L"minOccurs"] == L"0" ? 0 : min (), - s[L"maxOccurs"] && s[L"maxOccurs"] != L"1" ? 0 : max ()); + push_cardinality (s[L"minOccurs"] == L"0" ? 0 : minimum (), + s[L"maxOccurs"] && s[L"maxOccurs"] != L"1" ? 0 : maximum ()); push (s); @@ -1129,27 +1121,27 @@ namespace XSC void Parser:: element (XML::Element const& e, bool global) { - unsigned long min (this->min ()); - unsigned long max (this->max ()); + unsigned long minimum (this->minimum ()); + unsigned long maximum (this->maximum ()); if (e[L"minOccurs"]) { string value = e[L"minOccurs"]; std::wistringstream istr (value); - istr >> min; + istr >> minimum; } if (e[L"maxOccurs"]) { if (e[L"maxOccurs"] == L"unbounded") - max = std::numeric_limits ::max (); + maximum = (std::numeric_limits ::max) (); else { string value (e[L"maxOccurs"]); std::wistringstream istr (value); - istr >> max; + istr >> maximum; } } @@ -1160,12 +1152,12 @@ namespace XSC qualified = form == L"qualified"; } - if (trace_) std::wcout << "element min " << min << " max " << max + if (trace_) std::wcout << "element min " << minimum << " max " << maximum << " qualified " << qualified << std::endl; if (string name = e[L"name"]) { - Element& node (root_schema_->new_node (min, max, qualified)); + Element& node (root_schema_->new_node (minimum, maximum, qualified)); root_schema_->new_edge (scope (), node, name); if (string type = e[L"type"]) @@ -1227,7 +1219,7 @@ namespace XSC string uq_name (XML::uq_name (ref)); string ns_name (XML::ns_name (e, ref)); - Element& node (root_schema_->new_node (min, max, qualified)); + Element& node (root_schema_->new_node (minimum, maximum, qualified)); root_schema_->new_edge (scope (), node, uq_name); try diff --git a/XSC/Parser.hpp b/XSC/Parser.hpp index dd70f23..2a0c1b8 100644 --- a/XSC/Parser.hpp +++ b/XSC/Parser.hpp @@ -40,7 +40,7 @@ namespace XSC { } - string (string s, size_type pos, size_type n) + string (string const& s, size_type pos, size_type n) : std::wstring (s, pos, n) { } @@ -61,7 +61,7 @@ namespace XSC { string r (Xerces::XMLString::stringLen (s), L'0'); - for (std::size_t i (0); *s != XMLCh (0); ++s, ++i) + for (std::size_t i {}; *s != XMLCh (0); ++s, ++i) { r[i] = *s; } @@ -74,12 +74,12 @@ namespace XSC std::unique_ptr transcode (string const& s) { - std::size_t l (s.length ()); + std::size_t const l (s.length ()); auto r = std::make_unique (l + 1); XMLCh* ir (r.get ()); - for (std::size_t i (0); i < l; ++ir, ++i) + for (std::size_t i {}; i < l; ++ir, ++i) { *ir = static_cast(s[i]); //std::wcerr << s[i] << "->" << *ir << std::endl; @@ -95,7 +95,7 @@ namespace XSC class Element { public: - Element (Xerces::DOMElement* e) + explicit Element (Xerces::DOMElement* e) : e_ (e), name_ (transcode (e->getLocalName ())), namespace__ (transcode (e->getNamespaceURI ())) @@ -118,7 +118,7 @@ namespace XSC Element parent () const { - return dynamic_cast(e_->getParentNode ()); + return Element (dynamic_cast (e_->getParentNode ())); } public: @@ -151,7 +151,7 @@ namespace XSC string prefix (string const& n) { - std::size_t i (0); + std::size_t i {}; while (i < n.length () && n[i] != L':') ++i; //std::wcerr << "prefix " << n << " " @@ -164,7 +164,7 @@ namespace XSC string uq_name (string const& n) { - std::size_t i (0); + std::size_t i {}; while (i < n.length () && n[i] != L':') ++i; return string (n.c_str () + (i == n.length () ? 0 : i + 1)); @@ -360,14 +360,14 @@ namespace XSC } unsigned long - min () const + minimum () const { if (cardinality_stack_.empty ()) return 1; else return cardinality_stack_.top ().min_; } unsigned long - max () const + maximum () const { if (cardinality_stack_.empty ()) return 1; else return cardinality_stack_.top ().max_; @@ -396,7 +396,7 @@ namespace XSC struct Iterator { Iterator (Xerces::DOMElement* e) - : l_ (e->getChildNodes ()), i_ (0) + : l_ (e->getChildNodes ()), i_ {} { } diff --git a/XSC/SemanticGraph/Element.hpp b/XSC/SemanticGraph/Element.hpp index ec99469..e0069f8 100644 --- a/XSC/SemanticGraph/Element.hpp +++ b/XSC/SemanticGraph/Element.hpp @@ -18,13 +18,13 @@ namespace XSC static_type_info (); unsigned long - min () const + minimum () const { return this->min_; } unsigned long - max () const + maximum () const { return this->max_; } diff --git a/XSC/be/CXX/Elements.hpp b/XSC/be/CXX/Elements.hpp index 4918e88..adf0aeb 100644 --- a/XSC/be/CXX/Elements.hpp +++ b/XSC/be/CXX/Elements.hpp @@ -522,7 +522,7 @@ struct CopyRequiredMembers : Traversal::Element, Traversal::Attribute void traverse (SemanticGraph::Element& e) override { - if (e.max () == 1) + if (e.maximum () == 1) required = true; } @@ -560,7 +560,7 @@ struct ConstructorRequiredMembers : Traversal::Enumeration, void traverse (SemanticGraph::Element& e) override { - if (e.min () >= 1) + if (e.minimum () >= 1) required = true; } @@ -602,7 +602,7 @@ struct ConstructorOptionalMembers : Traversal::Element, void traverse (SemanticGraph::Element& e) override { - if (e.min () == 0) + if (e.minimum () == 0) optional = true; } diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index c297595..2b4f63d 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -4,22 +4,15 @@ #include "Header.hpp" #include "Elements.hpp" +#include #include +#include #include "XSC/SemanticGraph.hpp" #include "XSC/Traversal.hpp" #include "CCF/CodeGenerationKit/Regex.hpp" -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif - namespace { struct Base : Traversal::Type, protected virtual Context @@ -70,11 +63,11 @@ namespace string type (type_name (e)); string name (e.name ()); - if (e.min () == 1 && e.max () == 1) + if (e.minimum () == 1 && e.maximum () == 1) { os << comma () << type << " const& " << id (name) << "__"; } - else if (e.min () >= 1) + else if (e.minimum () >= 1) { os << comma () << name << "_container_type const& " @@ -146,11 +139,11 @@ namespace void traverse (SemanticGraph::Element& e) override { - if (e.min () == 0) + if (e.minimum () == 0) { string name (e.name ()); string argument (id (e.name ())); - if (e.max () == 1) + if (e.maximum () == 1) os << comma () << "::XSCRT::OptionalArg<" << type_name (e) << "> " << argument << "__ = std::nullopt"; else @@ -224,9 +217,8 @@ namespace string char_type (this->char_type); //Check if the type is an IDREF - size_t idref_ptr = 0; - std::wstring idref_str (L"::XMLSchema::IDREF<"); - idref_ptr = type.find(idref_str); + std::wstring_view const idref_str (L"::XMLSchema::IDREF<"); + std::wstring_view::size_type const idref_ptr (type.find (idref_str)); string container; @@ -239,7 +231,7 @@ namespace os << Indentation::unindent << "public:" << std::endl << Indentation::indent; - if (c.max () != 1) + if (c.maximum () != 1) { string accessor_name (sequence_accessor_name (c)); @@ -309,7 +301,7 @@ namespace break; } //Return referenced item if an IDREF - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << "XSCRT::Type* get_" << name << "_ptr (const " << string_type <<"& idref);"; @@ -326,7 +318,7 @@ namespace os << name << "_container_type " << id(name) << "_" << (this->read_only_ && this->cppmode_ != CPPMODE::CPP03 ? L" {};" : L";"); } - else if (c.min () == 0) + else if (c.minimum () == 0) { // optional if (!this->optional_via_if_set ()) @@ -350,7 +342,7 @@ namespace os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03)) { if (!this->read_only_) { @@ -386,7 +378,7 @@ namespace os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << "::XSCRT::Type* get_" << id (name) << "_ptr ( void );\n"; @@ -444,9 +436,8 @@ namespace string type (type_name (a)); //Check if the type is an IDREF - size_t idref_ptr = 0; - std::wstring idref_str (L"::XMLSchema::IDREF<"); - idref_ptr = type.find(idref_str); + std::wstring_view const idref_str (L"::XMLSchema::IDREF<"); + std::wstring_view::size_type const idref_ptr (type.find (idref_str)); os << Indentation::unindent << "public:" << std::endl << Indentation::indent; @@ -474,7 +465,7 @@ namespace os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << "::XSCRT::Type* get_" << id (name) << "_ptr ();\n"; @@ -509,7 +500,7 @@ namespace os << "void " << id (name) << " (" << type << " const&);"; //Added for IDREF case - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << "::XSCRT::Type* get_" << id (name) << "_ptr ( void );\n"; @@ -640,13 +631,13 @@ namespace return; // CDR Insertion/Extraction Operators - bool reader = 0; + bool reader {}; if (this->cdr_reader_generation_) { os << "// read" << std::endl; - reader = 1; + reader = true; os << Indentation::unindent << "public:" << std::endl << Indentation::indent; os << "static bool" << std::endl @@ -654,7 +645,7 @@ namespace << " (::XMLSchema::CDR_InputStream &," << std::endl; - for (size_t j =0; j < name.length () + 5; j++) + for (std::size_t j {}; j < name.length () + 5; ++j) os << " "; os << " ::XMLSchema::cdr_arg_traits < " << name << " >::inout_type);" << std::endl; @@ -972,11 +963,11 @@ namespace os << "Value v_" << (this->cppmode_ == CPPMODE::CPP03 ? L";" : L" {};"); // CDR Insertion/Extraction Operators - bool reader = 0; + bool reader {}; if (this->cdr_reader_generation_) { os << "// read" << std::endl; - reader = 1; + reader = true; os << Indentation::unindent << "public:" << std::endl << Indentation::indent; os << "static bool" << std::endl @@ -984,7 +975,7 @@ namespace << " (::XMLSchema::CDR_InputStream &," << std::endl; - for (size_t j =0; j < name.length () + 5; j++) + for (std::size_t j {}; j < name.length () + 5; ++j) os << " "; os << " ::XMLSchema::cdr_arg_traits < " << name @@ -1105,7 +1096,7 @@ namespace traverse (i.file ()); } - virtual void + void traverse (std::filesystem::path const& f) { std::string name (regex::perl_s (f.string (), hxx_expr.c_str ())); diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 71febb8..05ffcea 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -5,21 +5,13 @@ #include "Elements.hpp" #include +#include #include "XSC/SemanticGraph.hpp" #include "XSC/Traversal.hpp" #include "CCF/CodeGenerationKit/Regex.hpp" -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif - namespace { struct Member : Traversal::Element, @@ -40,11 +32,10 @@ namespace //bool ra_sequence (this->generate_ra_sequences_); //Check if the type is an IDREF - std::string::size_type idref_ptr = 0; - std::wstring idref_str (L"::XMLSchema::IDREF<"); - idref_ptr = type.find(idref_str); + std::wstring_view const idref_str (L"::XMLSchema::IDREF<"); + std::wstring::size_type const idref_ptr (type.find (idref_str)); - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { // optional if (this->optional_via_if_set ()) @@ -71,7 +62,7 @@ namespace } // Return referenced item if an IDREF - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << i @@ -134,7 +125,7 @@ namespace << "}"; } } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { // one os << i @@ -142,7 +133,7 @@ namespace << "{" << "return *" << id (name) << "_;" << "}"; - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << i @@ -230,7 +221,7 @@ namespace } // add IDREF access method - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << i @@ -285,9 +276,8 @@ namespace string type (type_name (a)); //Check if the type is an IDREF - std::string::size_type idref_ptr = 0; - std::wstring idref_str (L"::XMLSchema::IDREF<"); - idref_ptr = type.find(idref_str); + std::wstring_view const idref_str (L"::XMLSchema::IDREF<"); + std::wstring::size_type const idref_ptr (type.find (idref_str)); if (a.optional ()) { @@ -324,7 +314,7 @@ namespace } // Return a pointer to the referenced item - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << i @@ -395,7 +385,7 @@ namespace << "}"; // Return a pointer to the referenced item - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03) && + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03) && !this->read_only_) { os << i @@ -461,18 +451,18 @@ namespace string type (type_name (e)); string name (e.name ()); - if (optional_arguments_ && e.min () == 0) + if (optional_arguments_ && e.minimum () == 0) { - if (e.max () == 1) + if (e.maximum () == 1) os << comma () << "::XSCRT::OptionalArg<" << type << "> " << id (name) << "__"; else os << comma () << name << "_container_type const& " << id (name) << "__"; } - else if (!optional_arguments_ && e.min () == 1 && e.max () == 1) + else if (!optional_arguments_ && e.minimum () == 1 && e.maximum () == 1) { os << comma () << type << " const& " << id (name) << "__"; } - else if (!optional_arguments_ && e.min () >= 1) + else if (!optional_arguments_ && e.minimum () >= 1) { os << comma () << name << "_container_type const& " @@ -809,15 +799,15 @@ namespace void traverse (SemanticGraph::Element& e) override { - if (optional_arguments_ && e.min () == 0) + if (optional_arguments_ && e.minimum () == 0) { os << comma () << id (e.name ()) << "__"; } - else if (!optional_arguments_ && e.min () == 1 && e.max () == 1) + else if (!optional_arguments_ && e.minimum () == 1 && e.maximum () == 1) { os << comma () << id (e.name ()) << "__"; } - else if (!optional_arguments_ && e.min () >= 1) + else if (!optional_arguments_ && e.minimum () >= 1) { os << comma () << id (e.name ()) << "__"; } @@ -889,7 +879,7 @@ namespace { ensure_base_class_initialization (); - if (this->cppmode_ == CPPMODE::CPP17 && e.min () == 0 && e.max () == 1) + if (this->cppmode_ == CPPMODE::CPP17 && e.minimum () == 0 && e.maximum () == 1) { ensure_base_class_initialization (); string name (id (e.name ())); @@ -897,13 +887,13 @@ namespace os << ", " << name << "_ (" << name << "__ ? std::make_unique<" << type << "> (*" << name << "__) : nullptr)" << std::endl; } - else if (this->cppmode_ == CPPMODE::CPP17 && e.min () == 0) + else if (this->cppmode_ == CPPMODE::CPP17 && e.minimum () == 0) { ensure_base_class_initialization (); string name (id (e.name ())); os << ", " << name << "_ (" << name << "__)" << std::endl; } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { // one string name (id (e.name ())); @@ -918,7 +908,7 @@ namespace os << ", " << name << "_ (new " << type << " (" << name << "__))" << std::endl; } } - else if (e.min () >= 1) + else if (e.minimum () >= 1) { // more than one string name (id (e.name ())); @@ -988,7 +978,7 @@ namespace void traverse (SemanticGraph::Element& e) override { - if (e.min () == 1 && e.max () == 1 && (this->cppmode_ == CPPMODE::CPP03)) + if (e.minimum () == 1 && e.maximum () == 1 && (this->cppmode_ == CPPMODE::CPP03)) { // one os << id (e.name ()) << "_->container (this);"; @@ -1050,7 +1040,7 @@ namespace base_class_initialized_ = true; } - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { // optional if (this->cppmode_ != CPPMODE::CPP03) @@ -1066,7 +1056,7 @@ namespace << "new " << type << " (*s." << name << "_) : " << nullptr_string << ")" << std::endl; } } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { // one if (this->cppmode_ != CPPMODE::CPP03) @@ -1152,7 +1142,7 @@ namespace { string name (e.name ()); - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { name = id (name); @@ -1163,7 +1153,7 @@ namespace << name << "_->container (this);"; } } - else if (e.min () == 1 && e.max () == 1 && this->cppmode_ == CPPMODE::CPP03) + else if (e.minimum () == 1 && e.maximum () == 1 && this->cppmode_ == CPPMODE::CPP03) { os << id (name) << "_->container (this);"; } @@ -1215,7 +1205,7 @@ namespace string name (e.name ()); string type (type_name (e)); - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { name = id (name); @@ -1237,7 +1227,7 @@ namespace << std::endl; } } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { name = id (name); diff --git a/XSC/be/CXX/ParserHeader.cpp b/XSC/be/CXX/ParserHeader.cpp index 0f7db85..3424c37 100644 --- a/XSC/be/CXX/ParserHeader.cpp +++ b/XSC/be/CXX/ParserHeader.cpp @@ -16,8 +16,8 @@ namespace { } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { string name (c.name ()); string type (type_name (c)); diff --git a/XSC/be/CXX/ParserSource.cpp b/XSC/be/CXX/ParserSource.cpp index 54e2056..ec67007 100644 --- a/XSC/be/CXX/ParserSource.cpp +++ b/XSC/be/CXX/ParserSource.cpp @@ -16,8 +16,8 @@ namespace { } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { string name (c.name ()); string type (type_name (c)); diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index f01d511..1c9e684 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -11,15 +11,7 @@ #include #include - -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif +#include namespace { @@ -36,8 +28,8 @@ namespace first_ = true; } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { string name (c.name ()); string type (type_name (c)); @@ -64,7 +56,7 @@ namespace << "{"; first_ = false; - if (c.max () != 1) + if (c.maximum () != 1) { // sequence if (this->cppmode_ != CPPMODE::CPP03) @@ -81,7 +73,7 @@ namespace os << "add_" << name << " (t);"; } } - else if (c.min () == 0) + else if (c.minimum () == 0) { // optional if (this->read_only_) @@ -112,23 +104,21 @@ namespace } //Check if idref or id is the type - std::wstring idref_str (L"::XMLSchema::IDREF<"); - std::wstring id_str (L"::XMLSchema::ID<"); - std::wstring wchar_t_compare (L"wchar_t"); - std::wstring char_compare (L"char"); - std::string::size_type idref_ptr = type.find(idref_str); - std::string::size_type id_ptr = type.find(id_str); - - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + std::wstring_view const idref_str (L"::XMLSchema::IDREF<"); + std::wstring_view const id_str (L"::XMLSchema::ID<"); + std::wstring::size_type const idref_ptr (type.find (idref_str)); + std::wstring::size_type const id_ptr (type.find (id_str)); + + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03)) { - if (c.max() != 1) + if (c.maximum() != 1) { - if (this->char_type == char_compare) + if (this->char_type == L"char") { os << string_type << " temp (" << id(name); os << "_.back()->id());\n"; } - else if (this->char_type == wchar_t_compare) + else if (this->char_type == L"wchar_t") { os << string_type << " temp (ACE_TEXT_WCHAR_TO_TCHAR (" << id(name); os << "_.back()->id().c_str()));\n"; @@ -146,12 +136,12 @@ namespace } else { - if (this->char_type == char_compare) + if (this->char_type == L"char") { os << string_type << " temp (" << id(name); os << "_->id());\n"; } - else if (this->char_type == wchar_t_compare) + else if (this->char_type == L"wchar_t") { os << string_type << " temp (ACE_TEXT_WCHAR_TO_TCHAR ((*" << id(name); os << "_).id().c_str()));\n"; @@ -167,15 +157,15 @@ namespace //<< id(name) << "_).id().c_str(), dynamic_cast (this));\n"; } } - else if ((id_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + else if ((id_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03)) { - if (c.max() == 1) + if (c.maximum() == 1) { - if (this->char_type == char_compare) + if (this->char_type == L"char") { os << string_type << " temp ((*" << id(name) << "_));"; } - else if (this->char_type == wchar_t_compare) + else if (this->char_type == L"wchar_t") { os << string_type << " temp (ACE_TEXT_WCHAR_TO_TCHAR ((*" << id(name) << "_).c_str()));"; } @@ -188,12 +178,12 @@ namespace } else { - if (this->char_type == char_compare) + if (this->char_type == L"char") { os << string_type << " temp (" << id(name); os << "_.back()->c_str());\n"; } - else if (this->char_type == wchar_t_compare) + else if (this->char_type == L"wchar_t") { os << string_type << " temp (ACE_TEXT_WCHAR_TO_TCHAR (" << id(name); os << "_.back()->c_str()));\n"; @@ -230,8 +220,8 @@ namespace first_ = true; } - virtual void - traverse (Type& a) + void + traverse (Type& a) override { string name (a.name ()); string type (type_name (a)); @@ -271,23 +261,19 @@ namespace } //Check if idref or id is the type - std::string::size_type idref_ptr = 0; - std::string::size_type id_ptr = 0; - std::wstring idref_str (L"::XMLSchema::IDREF<"); - std::wstring id_str (L"::XMLSchema::ID<"); - std::wstring wchar_t_compare (L"wchar_t"); - std::wstring char_compare (L"char"); - idref_ptr = type.find(idref_str); - id_ptr = type.find(id_str); - - if ((idref_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + std::wstring_view const idref_str (L"::XMLSchema::IDREF<"); + std::wstring_view const id_str (L"::XMLSchema::ID<"); + std::wstring::size_type const idref_ptr (type.find (idref_str)); + std::wstring::size_type const id_ptr (type.find (id_str)); + + if ((idref_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03)) { - if (this->char_type == char_compare) + if (this->char_type == L"char") { os << string_type << " temp (" << id(name); os << "_->id());\n"; } - else if (this->char_type == wchar_t_compare) + else if (this->char_type == L"wchar_t") { os << string_type << " temp (ACE_TEXT_WCHAR_TO_TCHAR ((*" << id(name); os << "_).id().c_str()));\n"; @@ -310,13 +296,13 @@ namespace //"_).id(), dynamic_cast (this));\n"; } */ - else if ((id_ptr != std::string::npos) && (this->cppmode_ == CPPMODE::CPP03)) + else if ((id_ptr != std::wstring::npos) && (this->cppmode_ == CPPMODE::CPP03)) { - if (this->char_type == char_compare) + if (this->char_type == L"char") { os << string_type << " temp ((*" << id(name) << "_));"; } - else if (this->char_type == wchar_t_compare) + else if (this->char_type == L"wchar_t") { os << string_type << " temp (ACE_TEXT_WCHAR_TO_TCHAR ((*" << id(name) << "_).c_str()));"; } @@ -347,12 +333,12 @@ namespace void traverse (SemanticGraph::Element& e) override { - if (e.min () == 0) + if (e.minimum () == 0) return; string const name (e.name ()); - if (e.max () != 1) - os << "if (" << id (name) << "_.size () < " << e.min () << ")" + if (e.maximum () != 1) + os << "if (" << id (name) << "_.size () < " << e.minimum () << ")" << "throw std::invalid_argument (\"missing required XML element: " << name << "\");"; else @@ -401,8 +387,8 @@ namespace return (type.compare (bool_type) == 0); } - virtual void - traverse (SemanticGraph::Type& c) + void + traverse (SemanticGraph::Type& c) override { // Writing types that have extension base // from basic type @@ -470,13 +456,13 @@ namespace } } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { string name (e.name ()); string type (type_name (e)); - if (e.max () != 1) + if (e.maximum () != 1) { // Write sequence types after we write the attributes if (this->has_attributes_) @@ -486,7 +472,7 @@ namespace else this->write_sequence (e); } - else if (e.min () == 0) + else if (e.minimum () == 0) { // optional this->optional_element_list_.push_back (&e); @@ -519,8 +505,8 @@ namespace finally (); } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { string name (id (a.name ())); string type (type_name (a)); @@ -590,7 +576,7 @@ namespace void reset_type_attribute_settings () { - this->has_attributes_ = 0; + this->has_attributes_ = false; this->complex_list_.clear (); this->optional_element_list_.clear (); } @@ -1037,13 +1023,13 @@ namespace this->type_name_list_.push_back (element_name_); } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { string type (type_name (e)); string name (e.name ()); - if (e.max () != 1) + if (e.maximum () != 1) { // Sequence: Read sequences after creating // the element @@ -1051,7 +1037,7 @@ namespace // released elsewhere. So this is safe this->complex_list_.push_back (&e); } - else if (e.min () == 0) + else if (e.minimum () == 0) { this->optional_element_list_.push_back (&e); } @@ -1092,8 +1078,8 @@ namespace this->finally (); } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { string type (type_name (a)); string name (id (a.name ())); @@ -1116,7 +1102,7 @@ namespace void reset_type_attribute_settings () { - this->has_attributes_ = 0; + this->has_attributes_ = false; this->complex_list_.clear (); this->type_name_list_.clear (); this->optional_attribute_list_.clear (); @@ -1124,7 +1110,7 @@ namespace } void - add_attribute (string &name) + add_attribute (string const& name) { // This attribute should be added only // if we read this. so check if we read this @@ -1263,8 +1249,8 @@ namespace } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { if (c.named ()) name = id (c.name ()); @@ -1286,8 +1272,8 @@ namespace } } - virtual void - pre (Type& c) + void + pre (Type& c) override { string type (type_name (c)); @@ -1298,8 +1284,8 @@ namespace using Traversal::Complex::names; - virtual void - names (Type& c) + void + names (Type& c) override { bool he (has (c)); bool ha (has (c)); @@ -1341,8 +1327,8 @@ namespace } } - virtual void - post (Type& ) + void + post (Type& ) override { os << "}"; } @@ -1360,8 +1346,8 @@ namespace return ret_val; } - virtual void - insertion_extraction (Type &c) + void + insertion_extraction (Type &c) override { // Check if one needs to generate read/write operations // for this type @@ -1442,8 +1428,8 @@ namespace { } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { bool r (true); @@ -1457,8 +1443,8 @@ namespace node_traverser (*this); } - virtual void - traverse (SemanticGraph::Complex& c) + void + traverse (SemanticGraph::Complex& c) override { if (has (c) || has (c)) v_ = false; @@ -1491,8 +1477,8 @@ namespace } - virtual void - pre (Type& c) + void + pre (Type& c) override { os << scope << "::" << name << " (" << xml_attribute_type << " const& a)" << std::endl << ":" << std::endl @@ -1500,8 +1486,8 @@ namespace << "{"; } - virtual void - post (Type&) + void + post (Type&) override { os << "}"; } @@ -1517,8 +1503,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { if (this->cppmode_ != CPPMODE::CPP17) { @@ -1545,8 +1531,8 @@ namespace first_ = true; } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { string name (e.name ()); @@ -1572,8 +1558,8 @@ namespace names_static_.node_traverser (static_enumerator_); } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { if (e.named ()) name = id (e.name ()); @@ -1678,8 +1664,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); diff --git a/XSC/be/CXX/TraversalHeader.cpp b/XSC/be/CXX/TraversalHeader.cpp index 95853dc..deb9f84 100644 --- a/XSC/be/CXX/TraversalHeader.cpp +++ b/XSC/be/CXX/TraversalHeader.cpp @@ -6,15 +6,6 @@ #include "XSC/SemanticGraph.hpp" #include "XSC/Traversal.hpp" -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif - namespace { struct Member : Traversal::Element, @@ -32,8 +23,8 @@ namespace os << "virtual void " << name << " (" << type << ");" << std::endl; } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { // Anonymous types cannot be traversed. //if (!e.type ().named ()) @@ -41,7 +32,7 @@ namespace string name (e.name ()); - if (e.max () != 1) + if (e.maximum () != 1) { // sequence @@ -66,13 +57,13 @@ namespace // name_none - if (e.min () == 0) + if (e.minimum () == 0) { declaration (name + L"_none", L"Type&"); declaration (name + L"_none", L"Type const&"); } } - else if (e.min () == 0) + else if (e.minimum () == 0) { // optional @@ -96,8 +87,8 @@ namespace } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { // Anonymous types cannot be traversed. if (!a.type ().named ()) return; @@ -138,8 +129,8 @@ namespace names_.node_traverser (member_); } - virtual void - pre (Type& c) + void + pre (Type& c) override { os << "// From " << type_name (c) << std::endl; } @@ -171,8 +162,8 @@ namespace names_.node_traverser (member_); } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { // We need to get the name of the element. The name would // be already set if it was an anonymous type. @@ -190,8 +181,8 @@ namespace } } - virtual void - pre (Type& c) + void + pre (Type& c) override { string virtual_string (this->cppmode_ == CPPMODE::CPP03 ? L"virtual " : L""); string override_string (this->cppmode_ != CPPMODE::CPP03 ? L" override" : L""); @@ -211,8 +202,8 @@ namespace os << "virtual void pre (Type const&);" << std::endl; } - virtual void - post (Type& ) + void + post (Type& ) override { // post () os << "virtual void post (Type&);" << std::endl; @@ -241,8 +232,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { string name ((this->name_ != L"") ? name_: id (e.name ())); string type (type_name (e)); @@ -269,8 +260,8 @@ namespace { } - virtual void - pre (Type& n) + void + pre (Type& n) override { Namespace::pre (n); @@ -278,8 +269,8 @@ namespace << "{"; } - virtual void - post (Type& n) + void + post (Type& n) override { os << "}"; @@ -294,8 +285,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); diff --git a/XSC/be/CXX/TraversalSource.cpp b/XSC/be/CXX/TraversalSource.cpp index f6be3c7..1a2e747 100644 --- a/XSC/be/CXX/TraversalSource.cpp +++ b/XSC/be/CXX/TraversalSource.cpp @@ -6,15 +6,6 @@ #include "XSC/SemanticGraph.hpp" #include "XSC/Traversal.hpp" -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif - namespace { struct Member : Traversal::Element, @@ -58,8 +49,8 @@ namespace os << "}"; } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { // Anonymous types cannot be traversed. //if (!e.type ().named ()) @@ -69,7 +60,7 @@ namespace string name (e.name ()); string type (type_name (e)); - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { // optional @@ -87,7 +78,7 @@ namespace << "{" << "}"; } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { // one @@ -136,7 +127,7 @@ namespace << name << "_post (o);" << "}"; - if (e.min () == 0) + if (e.minimum () == 0) os << "else " << name << "_none (o);"; os << "}"; @@ -170,7 +161,7 @@ namespace << name << "_post (o);" << "}"; - if (e.min () == 0) + if (e.minimum () == 0) os << "else " << name << "_none (o);"; os << "}"; @@ -212,7 +203,7 @@ namespace << "}"; // name_none - if (e.min () == 0) + if (e.minimum () == 0) { os << "void " << scope << "::" << name << "_none (Type&)" @@ -228,8 +219,8 @@ namespace } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { // Anonymous types cannot be traversed. //if (!a.type ().named ()) @@ -304,15 +295,15 @@ namespace { } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { // Anonymous types cannot be traversed. //if (!e.type ().named ()) return; string name (e.name ()); - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { // optional if (!this->optional_via_if_set ()) @@ -324,7 +315,7 @@ namespace << id (name) << " (o);" << "else " << name << "_none (o);"; } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { // one os << id (name) << " (o);"; @@ -336,8 +327,8 @@ namespace } } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { // Anonymous types cannot be traversed. //if (!a.type ().named ()) return; @@ -408,8 +399,8 @@ namespace call_names_.node_traverser (call_member_); } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { if (c.named ()) name_ = id (c.name ()); @@ -431,8 +422,8 @@ namespace } } - virtual void - pre (Type& c) + void + pre (Type& c) override { //string name (id (name_)); @@ -475,8 +466,8 @@ namespace << "}"; } - virtual void - post (Type&) + void + post (Type&) override { // string name (id (name_)); @@ -519,8 +510,8 @@ namespace { } - virtual void - pre (Type& n) + void + pre (Type& n) override { Namespace::pre (n); @@ -529,8 +520,8 @@ namespace } - virtual void - post (Type& n) + void + post (Type& n) override { os << "}"; @@ -545,8 +536,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); diff --git a/XSC/be/CXX/TypeInfoSource.cpp b/XSC/be/CXX/TypeInfoSource.cpp index 9bf2b6c..558c40b 100644 --- a/XSC/be/CXX/TypeInfoSource.cpp +++ b/XSC/be/CXX/TypeInfoSource.cpp @@ -16,8 +16,8 @@ namespace { } - virtual void - traverse (SemanticGraph::Type& c) + void + traverse (SemanticGraph::Type& c) override { string name (type_name (c)); @@ -43,8 +43,8 @@ namespace names_anonymous_.node_traverser (anonymous_type); } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { if (c.named ()) name_ = id (c.name ()); @@ -63,8 +63,8 @@ namespace } } - virtual void - pre (Type& c) + void + pre (Type& c) override { //@@ cache name as a member? @@ -77,16 +77,16 @@ namespace << std::endl; } - virtual void - inherits_none (Type& ) + void + inherits_none (Type& ) override { os << "nf.add_base (::XSCRT::ExtendedTypeInfo::Access::public_, " << "false, typeid (::XSCRT::Type));"; } - virtual void - post (Type& c) + void + post (Type& c) override { os << "::XSCRT::extended_type_info_map ().insert (" << "std::make_pair (id, nf));" @@ -120,8 +120,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { string name ((this->name_ != L"") ? name_ : id (e.name ())); @@ -154,8 +154,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); @@ -191,8 +191,8 @@ namespace { } - virtual void - pre (Type& n) + void + pre (Type& n) override { Namespace::pre (n); @@ -204,8 +204,8 @@ namespace } - virtual void - post (Type& n) + void + post (Type& n) override { os << "}"; diff --git a/XSC/be/CXX/Validator.cpp b/XSC/be/CXX/Validator.cpp index 70ef9f8..fc5731a 100644 --- a/XSC/be/CXX/Validator.cpp +++ b/XSC/be/CXX/Validator.cpp @@ -43,8 +43,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); @@ -67,8 +67,8 @@ namespace { } - virtual void - traverse (Type& a) + void + traverse (Type& a) override { SemanticGraph::Type& t (a.type ()); @@ -96,8 +96,8 @@ namespace names_.node_traverser (attribute_); } - virtual void - traverse (SemanticGraph::Complex& c) + void + traverse (SemanticGraph::Complex& c) override { traverse (static_cast (c)); @@ -125,8 +125,8 @@ namespace Traversal::Complex::traverse (c); } - virtual void - traverse (SemanticGraph::Type& t) + void + traverse (SemanticGraph::Type& t) override { if (t.named ()) { diff --git a/XSC/be/CXX/WriterHeader.cpp b/XSC/be/CXX/WriterHeader.cpp index 778dc5c..a0d0a26 100644 --- a/XSC/be/CXX/WriterHeader.cpp +++ b/XSC/be/CXX/WriterHeader.cpp @@ -7,15 +7,6 @@ #include "XSC/SemanticGraph.hpp" #include "XSC/Traversal.hpp" -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif - namespace { struct Member : Traversal::Element, @@ -27,8 +18,8 @@ namespace { } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { // Anonymous types cannot be traversed. //if (!e.type ().named ()) @@ -36,7 +27,7 @@ namespace string name (e.name ()); - if (e.min () == 0 && e.max () == 1) + if (e.minimum () == 0 && e.maximum () == 1) { if (this->cppmode_ == CPPMODE::CPP03) { @@ -54,7 +45,7 @@ namespace << id (name) << " (Type const&);" << std::endl; } - else if (e.min () == 1 && e.max () == 1) + else if (e.minimum () == 1 && e.maximum () == 1) { if (this->cppmode_ == CPPMODE::CPP03) { @@ -126,8 +117,8 @@ namespace } } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { // Anonymous types cannot be traversed. //if (!a.type ().named ()) @@ -169,15 +160,15 @@ namespace // os << "virtual " << type << "," << std::endl; //} - virtual void - traverse (SemanticGraph::IdRef&) + void + traverse (SemanticGraph::IdRef&) override { os << "virtual ::XMLSchema::Writer::IDREF<" << char_type << ">, " << std::endl; } - virtual void - fundamental_type (SemanticGraph::FundamentalType & t) + void + fundamental_type (SemanticGraph::FundamentalType & t) override { string name (fundamental_type_name (t)); @@ -214,8 +205,8 @@ namespace inherits_.node_traverser (base_); } - virtual void - traverse (Type & c) + void + traverse (Type & c) override { // We need to get the name of the element. The name would // be already set if it was an anonymous type. @@ -233,8 +224,8 @@ namespace } } - virtual void - pre (Type& c) + void + pre (Type& c) override { os << "struct " << name_ << " : Traversal::" << scope << "," << std::endl; @@ -277,8 +268,8 @@ namespace << std::endl; } - virtual void - post (Type& ) + void + post (Type& ) override { string default_string (this->cppmode_ != CPPMODE::CPP03 ? L" = default" : L""); os << Indentation::unindent << "protected:" << std::endl << Indentation::indent @@ -306,8 +297,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { string name ((this->name_ != L"") ? name_ : id (e.name ())); string type (type_name (e)); @@ -360,8 +351,8 @@ namespace { } - virtual void - pre (Type& n) + void + pre (Type& n) override { Namespace::pre (n); @@ -369,8 +360,8 @@ namespace << "{"; } - virtual void - post (Type& n) + void + post (Type& n) override { os << "}"; @@ -386,8 +377,8 @@ namespace { } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { string name (c.name ()); string type (fq_name (c.type ())); @@ -412,8 +403,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); diff --git a/XSC/be/CXX/WriterSource.cpp b/XSC/be/CXX/WriterSource.cpp index adc616d..674a84e 100644 --- a/XSC/be/CXX/WriterSource.cpp +++ b/XSC/be/CXX/WriterSource.cpp @@ -6,15 +6,6 @@ #include "XSC/SemanticGraph.hpp" #include "XSC/Traversal.hpp" -#if defined (_WINDOWS) -# if defined (min) -# undef min -# endif -# if defined (max) -# undef max -# endif -#endif - namespace { struct Member : Traversal::Element, @@ -26,8 +17,8 @@ namespace { } - virtual void - traverse (SemanticGraph::Element& e) + void + traverse (SemanticGraph::Element& e) override { // Anonymous types cannot be traversed. //if (!e.type ().named ()) @@ -39,7 +30,7 @@ namespace bool q (e.qualified ()); - if (e.max () != 1) + if (e.maximum () != 1) { // sequence @@ -85,8 +76,8 @@ namespace } } - virtual void - traverse (SemanticGraph::Attribute& a) + void + traverse (SemanticGraph::Attribute& a) override { // Anonymous types cannot be traversed. //if (!a.type ().named ()) @@ -140,23 +131,23 @@ namespace { } - virtual void - traverse (SemanticGraph::Type& t) + void + traverse (SemanticGraph::Type& t) override { string type (type_name (t, L"Writer")); os << type << "::traverse (o);"; } - virtual void - traverse (SemanticGraph::IdRef&) + void + traverse (SemanticGraph::IdRef&) override { os << "::XMLSchema::Writer::IDREF<" << char_type << ">" << "::traverse (o);"; } - virtual void - fundamental_type (SemanticGraph::FundamentalType& t) + void + fundamental_type (SemanticGraph::FundamentalType& t) override { string name (fundamental_type_name (t)); @@ -193,8 +184,8 @@ namespace names_anonymous_.node_traverser (anonymous_type); } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { if (c.named ()) name_ = id (c.name ()); @@ -216,8 +207,8 @@ namespace } } - virtual void - pre (Type& c) + void + pre (Type& c) override { string name (id (name_)); @@ -267,8 +258,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { string name (e.name ()); string type (type_name (e)); @@ -292,8 +283,8 @@ namespace names_.node_traverser (enumerator_); } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { string name ((this->name_ != L"") ? id(name_) : id (c.name ())); @@ -350,8 +341,8 @@ namespace { } - virtual void - pre (Type& n) + void + pre (Type& n) override { Namespace::pre (n); @@ -361,8 +352,8 @@ namespace } - virtual void - post (Type& n) + void + post (Type& n) override { os << "}"; @@ -387,8 +378,8 @@ namespace edge_traverser (belongs_); } - virtual void - traverse (SemanticGraph::Complex& c) + void + traverse (SemanticGraph::Complex& c) override { if (check (c)) { @@ -408,8 +399,8 @@ namespace // } //} - virtual void - traverse (SemanticGraph::IdRef& r) + void + traverse (SemanticGraph::IdRef& r) override { if (check (r)) { @@ -418,8 +409,8 @@ namespace } } - virtual void - fundamental_type (SemanticGraph::FundamentalType& t) + void + fundamental_type (SemanticGraph::FundamentalType& t) override { if (check (t)) { @@ -473,8 +464,8 @@ namespace { } - virtual void - traverse (Type& e) + void + traverse (Type& e) override { SemanticGraph::Type& t (e.type ()); @@ -504,8 +495,8 @@ namespace { } - virtual void - traverse (Type& c) + void + traverse (Type& c) override { string name (c.name ()); string type (type_name (c)); diff --git a/XSC/be/IDL/Declaration.cpp b/XSC/be/IDL/Declaration.cpp index b0d2e5a..556ce9e 100644 --- a/XSC/be/IDL/Declaration.cpp +++ b/XSC/be/IDL/Declaration.cpp @@ -54,7 +54,7 @@ namespace << "{"; } - virtual void + void names_next (Type&) { os << "," << std::endl; diff --git a/XSC/be/IDL/Definition.cpp b/XSC/be/IDL/Definition.cpp index 40a43b8..4546f31 100644 --- a/XSC/be/IDL/Definition.cpp +++ b/XSC/be/IDL/Definition.cpp @@ -11,14 +11,6 @@ using namespace IDL; -#if defined (min) -#undef min -#endif - -#if defined (max) -#undef max -#endif - namespace { struct Base : Traversal::Type, @@ -68,7 +60,7 @@ namespace os << "// " << name << std::endl; - if (c.max () != 1) + if (c.maximum () != 1) { string name_seq (id (name + L"_seq")); @@ -77,7 +69,7 @@ namespace << "public " << name_seq << " " << id (name) << ";"; } - else if (c.min () == 0) + else if (c.minimum () == 0) { // optional os << "boolean " << name << "_p ();" @@ -199,7 +191,7 @@ namespace traverse (i.file ()); } - virtual void + void traverse (std::filesystem::path const& f) { std::string name (regex::perl_s (f.string (), expr_)); diff --git a/XSC/be/IDL/Elements.hpp b/XSC/be/IDL/Elements.hpp index 03d120a..ac45a94 100644 --- a/XSC/be/IDL/Elements.hpp +++ b/XSC/be/IDL/Elements.hpp @@ -252,8 +252,8 @@ namespace IDL { } - virtual void - traverse (typename X::Type&) + void + traverse (typename X::Type&) override { v_ = true; } From 7a7c3e0c4ca08e015945b9f7a92f53147be11673 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 13:55:15 +0100 Subject: [PATCH 23/30] Test ACE XML utility edge cases --- Tests/XMLUtils/runtime.cpp | 103 +++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/Tests/XMLUtils/runtime.cpp b/Tests/XMLUtils/runtime.cpp index 610271c..a02256c 100644 --- a/Tests/XMLUtils/runtime.cpp +++ b/Tests/XMLUtils/runtime.cpp @@ -9,7 +9,9 @@ #include "generated_types.hpp" #include +#include #include +#include #include #include #include @@ -21,6 +23,11 @@ static_assert (std::is_copy_assignable_v); namespace { + struct CommaDecimalPoint : std::numpunct + { + char do_decimal_point () const override { return ','; } + }; + struct TypeTraverser : XSCRT::Traversal::Traverser { void traverse (XSCRT::Type&) override { ++visits; } @@ -79,6 +86,25 @@ int main () XSCRT::XML::string moved (std::move (assigned)); assert (XSCRT::XML::transcode (moved.c_str (), static_cast (nullptr)) == "copyable XML string"); + + XMLCh const surrogate_pair[] = { + static_cast (0xD83D), static_cast (0xDE00), static_cast (0) + }; + std::wstring const decoded (XSCRT::XML::transcode (surrogate_pair, nullptr)); + if (sizeof (wchar_t) == 2) + { + assert (decoded.size () == 2); + assert (decoded[0] == static_cast (0xD83D)); + assert (decoded[1] == static_cast (0xDE00)); + } + else + { + assert (decoded.size () == 1); + assert (decoded[0] == static_cast (0x1F600)); + } + + std::unique_ptr encoded (XSCRT::XML::transcode (decoded)); + assert (xercesc::XMLString::equals (encoded.get (), surrogate_pair)); } XERCES_CPP_NAMESPACE::DOMDocument* const document = @@ -208,6 +234,27 @@ int main () } assert (invalid_numeric_rejected); + assert (std::isinf (XSCRT::Details::parse_numeric ("INF"))); + assert (std::isinf (XSCRT::Details::parse_numeric ("-INF"))); + assert (std::signbit (XSCRT::Details::parse_numeric ("-INF"))); + assert (std::isnan (XSCRT::Details::parse_numeric ("NaN"))); + + std::locale const previous_locale {}; + std::locale::global (std::locale (previous_locale, new CommaDecimalPoint)); + assert ((XSCRT::Details::parse_numeric ("1.25") == 1.25)); + std::locale::global (previous_locale); + + bool invalid_special_numeric_rejected (false); + try + { + XSCRT::Details::parse_numeric ("INFjunk"); + } + catch (std::invalid_argument const&) + { + invalid_special_numeric_rejected = true; + } + assert (invalid_special_numeric_rejected); + XSCRT::XML::Element negative_unsigned (document->createElement ( static_cast (XML::XStr ("negative-unsigned")))); negative_unsigned.dom_element ()->appendChild ( @@ -384,4 +431,60 @@ int main () } assert (duplicate_rejected); } + + { + TestType old_root; + TestType new_root; + XMLSchema::ID moved ("moved"); + moved.container (std::addressof (old_root)); + moved.container (std::addressof (new_root)); + + XMLSchema::ID old_name_reused ("moved"); + old_name_reused.container (std::addressof (old_root)); + + XMLSchema::ID new_name_conflict ("moved"); + bool duplicate_rejected (false); + try + { + new_name_conflict.container (std::addressof (new_root)); + } + catch (std::logic_error const&) + { + duplicate_rejected = true; + } + assert (duplicate_rejected); + } + + { + TestType old_root; + TestType new_root; + XMLSchema::ID moving ("move"); + XMLSchema::ID destination_id ("move"); + moving.container (std::addressof (old_root)); + destination_id.container (std::addressof (new_root)); + + bool duplicate_rejected (false); + try + { + moving.container (std::addressof (new_root)); + } + catch (std::logic_error const&) + { + duplicate_rejected = true; + } + assert (duplicate_rejected); + assert (moving.container () == std::addressof (old_root)); + + XMLSchema::ID old_root_conflict ("move"); + bool old_registration_restored (false); + try + { + old_root_conflict.container (std::addressof (old_root)); + } + catch (std::logic_error const&) + { + old_registration_restored = true; + } + assert (old_registration_restored); + } } From 971c21847772d47a39f5cde47452d463615c1155 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 14:16:16 +0100 Subject: [PATCH 24/30] Allow implicit lvalue conversion for OptionalArg --- Tests/DanceX11/optional_copy.cpp | 2 ++ XSC/be/CXX/Header.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp index 1389943..ba7f0e1 100644 --- a/Tests/DanceX11/optional_copy.cpp +++ b/Tests/DanceX11/optional_copy.cpp @@ -3,6 +3,8 @@ static_assert (!std::is_convertible_v<::XMLSchema::IDREF, ::XSCRT::OptionalArg<::XMLSchema::IDREF>>); +static_assert (std::is_convertible_v<::XMLSchema::IDREF const&, + ::XSCRT::OptionalArg<::XMLSchema::IDREF>>); static_assert (std::is_constructible_v<::XSCRT::OptionalArg<::XMLSchema::IDREF>, ::XMLSchema::IDREF const&>); static_assert (!std::is_constructible_v<::XSCRT::OptionalArg<::XMLSchema::IDREF>, diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index 2b4f63d..ee431c1 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -1130,7 +1130,7 @@ generate_header (Context& ctx, << "OptionalArg (std::nullopt_t) noexcept : value_ (nullptr)" << std::endl << "{" << "}" - << "explicit OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl + << "OptionalArg (T const& value) noexcept : value_ (std::addressof (value))" << std::endl << "{" << "}" << "OptionalArg (T const&&) = delete;" << std::endl From 93d9230f4683fafe4c7b6f4efb3cd5a6455f612d Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 14:17:33 +0100 Subject: [PATCH 25/30] Test XMLSchema IDREF comparisons --- Tests/DanceX11/optional_copy.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Tests/DanceX11/optional_copy.cpp b/Tests/DanceX11/optional_copy.cpp index ba7f0e1..0afd87d 100644 --- a/Tests/DanceX11/optional_copy.cpp +++ b/Tests/DanceX11/optional_copy.cpp @@ -29,6 +29,11 @@ main () destination = source; XMLSchema::IDREF idref ("urn:idref"); + XMLSchema::IDREF same_idref ("urn:idref"); + XMLSchema::IDREF different_idref ("urn:other"); + if (idref != same_idref || idref == different_idref) + return 1; + Deployment::IdRef constructed ( std::nullopt, ::XSCRT::OptionalArg<::XMLSchema::IDREF> (idref)); if (constructed.idref_if_set () == nullptr) From 2ae7ed407271596937e7490d69ec7d23592fb827 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 14:45:25 +0100 Subject: [PATCH 26/30] Format required-member checks in generated code --- XSC/be/CXX/Source.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/XSC/be/CXX/Source.cpp b/XSC/be/CXX/Source.cpp index 1c9e684..5ca039a 100644 --- a/XSC/be/CXX/Source.cpp +++ b/XSC/be/CXX/Source.cpp @@ -338,11 +338,11 @@ namespace string const name (e.name ()); if (e.maximum () != 1) - os << "if (" << id (name) << "_.size () < " << e.minimum () << ")" + os << "if (" << id (name) << "_.size () < " << e.minimum () << ") " << "throw std::invalid_argument (\"missing required XML element: " << name << "\");"; else - os << "if (!" << id (name) << "_)" + os << "if (!" << id (name) << "_) " << "throw std::invalid_argument (\"missing required XML element: " << name << "\");"; } @@ -354,7 +354,7 @@ namespace return; string const name (a.name ()); - os << "if (!" << id (name) << "_)" + os << "if (!" << id (name) << "_) " << "throw std::invalid_argument (\"missing required XML attribute: " << name << "\");"; } From 62f0e05e6dc2389af607361d8ff0f118a39853bc Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 19:40:55 +0100 Subject: [PATCH 27/30] Omit field constructors from read-only types --- Tests/DanceX11/readonly_api.cpp | 21 ++++----------------- Tests/ReadOnly/enum_constructor_api.cpp | 4 +--- Tests/ReadOnly/readonly_api.cpp | 13 ++----------- XSC/be/CXX/Header.cpp | 6 +++--- XSC/be/CXX/Inline.cpp | 2 +- 5 files changed, 11 insertions(+), 35 deletions(-) diff --git a/Tests/DanceX11/readonly_api.cpp b/Tests/DanceX11/readonly_api.cpp index b11b00c..837b289 100644 --- a/Tests/DanceX11/readonly_api.cpp +++ b/Tests/DanceX11/readonly_api.cpp @@ -10,7 +10,6 @@ namespace using TopLevel = Deployment::TopLevelPackageDescription; using DataValue = Deployment::DataValue; using DataType = Deployment::DataType; - using TCKind = Deployment::TCKind; using Any = Deployment::Any; using ExternalReferenceEndpoint = Deployment::ExternalReferenceEndpoint; using Package = Deployment::PackageConfiguration; @@ -23,7 +22,6 @@ namespace static_assert (std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); static_assert (std::is_copy_constructible_v); - static_assert (std::is_constructible_v); static_assert (std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); static_assert (std::is_same_v ().begin ()), @@ -34,19 +32,8 @@ namespace LocalityKind::SameProcess), bool>); - [[maybe_unused]] Any make_char_any () - { - TCKind const kind (TCKind::tk_char); - DataType const type (kind); - DataValue const value {}; - return Any (type, value); - } - - [[maybe_unused]] ExternalReferenceEndpoint make_external_reference_endpoint () - { - ::XMLSchema::string const location ("location"); - bool const source_provider (true); - ::XMLSchema::boolean const provider (source_provider); - return ExternalReferenceEndpoint (location, provider); - } + static_assert (!std::is_constructible_v); + static_assert (!std::is_constructible_v const&, + ::XMLSchema::boolean const&>); } diff --git a/Tests/ReadOnly/enum_constructor_api.cpp b/Tests/ReadOnly/enum_constructor_api.cpp index 751ecc6..5d2b1e0 100644 --- a/Tests/ReadOnly/enum_constructor_api.cpp +++ b/Tests/ReadOnly/enum_constructor_api.cpp @@ -2,6 +2,4 @@ #include -static_assert (std::is_constructible_v>>); +static_assert (!std::is_constructible_v); diff --git a/Tests/ReadOnly/readonly_api.cpp b/Tests/ReadOnly/readonly_api.cpp index bdbc8ea..41d28e9 100644 --- a/Tests/ReadOnly/readonly_api.cpp +++ b/Tests/ReadOnly/readonly_api.cpp @@ -54,10 +54,6 @@ namespace using ReadOnly = ReadOnlyType; using Derived = DerivedWithoutMembers; using SimpleDerived = SimpleContentDerived; - using ConstOptionalArg = ::XSCRT::OptionalArg; - - static_assert (std::is_constructible_v); - static_assert (!std::is_constructible_v); static_assert (!std::is_default_constructible_v); static_assert (std::is_copy_constructible_v); static_assert (!std::is_move_constructible_v); @@ -66,16 +62,11 @@ namespace static_assert (!has_name_setter::value); static_assert (!has_optionalValue_presence_accessor::value); static_assert (std::is_copy_constructible_v); - static_assert (std::is_constructible_v< - SimpleDerived, - ::XSCRT::OptionalArg<::XMLSchema::string>, - ::XSCRT::OptionalArg<::XMLSchema::string>>); + static_assert (!std::is_constructible_v const&>); static_assert (!has_item_iterators::value); static_assert (!has_item_count::value); static_assert (std::is_constructible_v); - static_assert (std::is_constructible_v< - Derived, - ::XSCRT::OptionalArg<::XMLSchema::string>>); + static_assert (!std::is_constructible_v const&>); static_assert (std::is_same_v>>); static_assert (std::is_same_v ().name ()), diff --git a/XSC/be/CXX/Header.cpp b/XSC/be/CXX/Header.cpp index ee431c1..1407d25 100644 --- a/XSC/be/CXX/Header.cpp +++ b/XSC/be/CXX/Header.cpp @@ -679,14 +679,14 @@ namespace << Indentation::unindent << "public:" << std::endl << Indentation::indent; else if (has_constructor_required_members (c)) os << name << " () = delete;"; - else if (this->cppmode_ != CPPMODE::CPP17 || !has_constructor_optional_members (c)) + else os << name << " () = default;"; } bool const has_required (has_constructor_required_members (c)); bool const has_optional (this->cppmode_ == CPPMODE::CPP17 && has_constructor_optional_members (c)); - if (!this->read_only_ || has_required || has_optional) + if (!this->read_only_) { os << name << " ("; @@ -1117,7 +1117,7 @@ generate_header (Context& ctx, { ctx.os << "#include " << std::endl; ctx.os << "#include " << std::endl; - if (ctx.cppmode () == Context::CPPMODE::CPP17) + if (ctx.cppmode () == Context::CPPMODE::CPP17 && !ctx.read_only ()) { ctx.os << "#include " << std::endl << "#ifndef XSCRT_OPTIONAL_ARG_HPP" << std::endl diff --git a/XSC/be/CXX/Inline.cpp b/XSC/be/CXX/Inline.cpp index 05ffcea..9f0f749 100644 --- a/XSC/be/CXX/Inline.cpp +++ b/XSC/be/CXX/Inline.cpp @@ -588,7 +588,7 @@ namespace bool const default_constructor (this->cppmode_ != CPPMODE::CPP03 && !has_required && !has_optional); - if (!default_constructor) + if (!this->read_only_ && !default_constructor) { // c-tor os << i From 625051d76043817af2b6da95d6a41deaacf5517a Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Wed, 28 Oct 2026 19:53:29 +0100 Subject: [PATCH 28/30] Test XSCRT subtree ID rollback --- Tests/XMLUtils/xscrt_registration.cpp | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/Tests/XMLUtils/xscrt_registration.cpp b/Tests/XMLUtils/xscrt_registration.cpp index 9079571..0d7f455 100644 --- a/Tests/XMLUtils/xscrt_registration.cpp +++ b/Tests/XMLUtils/xscrt_registration.cpp @@ -10,6 +10,56 @@ namespace struct TestType : XSCRT::Type { }; + + void verify_subtree_rollback (std::string const &conflict_name) + { + TestType old_root; + TestType new_root; + TestType subtree; + XMLSchema::ID first (std::string ("first")); + XMLSchema::ID second (std::string ("second")); + XMLSchema::ID conflict (conflict_name); + + first.container (std::addressof (subtree)); + second.container (std::addressof (subtree)); + subtree.container (std::addressof (old_root)); + conflict.container (std::addressof (new_root)); + + bool move_rejected (false); + try + { + subtree.container (std::addressof (new_root)); + } + catch (std::logic_error const&) + { + move_rejected = true; + } + + assert (move_rejected); + assert (subtree.container () == std::addressof (old_root)); + + std::string const names[] {"first", "second"}; + for (std::string const &name : names) + { + XMLSchema::ID old_root_probe (name); + bool old_registration_restored (false); + try + { + old_root_probe.container (std::addressof (old_root)); + } + catch (std::logic_error const&) + { + old_registration_restored = true; + } + assert (old_registration_restored); + + if (name != conflict_name) + { + XMLSchema::ID new_root_probe (name); + new_root_probe.container (std::addressof (new_root)); + } + } + } } int main () @@ -33,4 +83,9 @@ int main () } assert (duplicate_rejected); + + // Trying both conflict positions covers a partial target registration + // regardless of the map's pointer ordering. + verify_subtree_rollback ("first"); + verify_subtree_rollback ("second"); } From d709a7cb1ab35541ba7b9445a20b1d8cf1f91fa7 Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 29 Oct 2026 08:32:25 +0100 Subject: [PATCH 29/30] Use ACE XML Utils MPC base project --- Tests/DanceX11/dancex11.mpc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tests/DanceX11/dancex11.mpc b/Tests/DanceX11/dancex11.mpc index 41050d5..00614f7 100644 --- a/Tests/DanceX11/dancex11.mpc +++ b/Tests/DanceX11/dancex11.mpc @@ -107,9 +107,8 @@ project (xsc_test_dancex11_optional_copy): xscrt { } } -project (xsc_test_dancex11_required_members): xscrt { +project (xsc_test_dancex11_required_members): xscrt, ace_xml_utils { after += xsc_test_dancex11_readonly - libs += ACE_XML_Utils Source_Files { Basic_Deployment_Data.readonly.cpp From 94afa3fed5ae1b9a2f3cfaf03fc23a2b15f4a49d Mon Sep 17 00:00:00 2001 From: Johnny Willemsen Date: Thu, 29 Oct 2026 09:58:10 +0100 Subject: [PATCH 30/30] Use try_emplace in C++17 generated type info --- XSC/be/CXX/TypeInfoSource.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/XSC/be/CXX/TypeInfoSource.cpp b/XSC/be/CXX/TypeInfoSource.cpp index 558c40b..e2a154b 100644 --- a/XSC/be/CXX/TypeInfoSource.cpp +++ b/XSC/be/CXX/TypeInfoSource.cpp @@ -88,9 +88,13 @@ namespace void post (Type& c) override { - os << "::XSCRT::extended_type_info_map ().insert (" - << "std::make_pair (id, nf));" - << "}"; + if (this->cppmode_ == CPPMODE::CPP17) + os << "::XSCRT::extended_type_info_map ().try_emplace (id, nf);"; + else + os << "::XSCRT::extended_type_info_map ().insert (" + << "std::make_pair (id, nf));"; + + os << "}"; // Go after anonymous types. names (c, names_anonymous_); @@ -134,10 +138,15 @@ namespace << std::endl << "nf.add_base (::XSCRT::ExtendedTypeInfo::Access::public_, " << "false, typeid (::XSCRT::Type));" - << std::endl - << "::XSCRT::extended_type_info_map ().insert (" - << "std::make_pair (id, nf));" - << "}" + << std::endl; + + if (this->cppmode_ == CPPMODE::CPP17) + os << "::XSCRT::extended_type_info_map ().try_emplace (id, nf);"; + else + os << "::XSCRT::extended_type_info_map ().insert (" + << "std::make_pair (id, nf));"; + + os << "}" << "};" << name << "TypeInfoInitializer " << name << "TypeInfoInitializer_;" << std::endl;