From 49383d1999132f1d55d41eb2862f2fb2d3a25878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Mon, 9 Sep 2024 22:29:46 +0200 Subject: [PATCH 01/11] Add macros for string_view support Define PUGI_ENABLE_STRING_VIEW to add string_view overloads when supported by the C++ standard --- src/pugixml.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 9af50df6..96670387 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -122,6 +122,26 @@ # endif #endif +// Detect if C++ standard supports 'string_view' (2017 or higher) +#ifndef PUGI_STRING_VIEW_SUPPORTED +# if defined(__cpp_lib_string_view) || __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define PUGI_STRING_VIEW_SUPPORTED 1 +# endif +#endif +// Enable 'string_view' support if requested and supported +#ifndef PUGI_HAS_STRING_VIEW +# if defined(PUGI_ENABLE_STRING_VIEW) && !defined(PUGIXML_NO_STL) +# ifdef PUGI_STRING_VIEW_SUPPORTED +# define PUGI_HAS_STRING_VIEW +# else +# warning "Support for std::string_view was requested but is not supported by your C++ standard" +# endif +# endif +#endif +#ifdef PUGI_HAS_STRING_VIEW +# include +#endif + // Character interface macros #ifdef PUGIXML_WCHAR_MODE # define PUGIXML_TEXT(t) L ## t From ee28175826106d498d2751f98eb5628853916748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Mon, 9 Sep 2024 22:35:32 +0200 Subject: [PATCH 02/11] Define string_view alias for the selected character type --- src/pugixml.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 96670387..b8d6b3c1 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -160,6 +160,10 @@ namespace pugi // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE typedef std::basic_string string_t; #endif + +#ifdef PUGI_HAS_STRING_VIEW + using string_view_t = std::basic_string_view; +#endif } // The PugiXML namespace From f4286474831b628d927ab66e8931caa1edb7afb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Tue, 10 Sep 2024 22:48:30 +0200 Subject: [PATCH 03/11] Add string_view_t overloads for set_name(), set_value() and set() --- src/pugixml.cpp | 35 +++++++++++++++++++++++++++++++++++ src/pugixml.hpp | 16 ++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 652d1e20..8fa592ef 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -5441,6 +5441,13 @@ namespace pugi return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs, size); } +#ifdef PUGI_HAS_STRING_VIEW + PUGI_IMPL_FN bool xml_attribute::set_name(const string_view_t rhs) + { + return set_name(rhs.data(), rhs.size()); + } +#endif + PUGI_IMPL_FN bool xml_attribute::set_value(const char_t* rhs) { if (!_attr) return false; @@ -5455,6 +5462,13 @@ namespace pugi return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, size); } +#ifdef PUGI_HAS_STRING_VIEW + PUGI_IMPL_FN bool xml_attribute::set_value(const string_view_t rhs) + { + return set_value(rhs.data(), rhs.size()); + } +#endif + PUGI_IMPL_FN bool xml_attribute::set_value(int rhs) { if (!_attr) return false; @@ -5848,6 +5862,13 @@ namespace pugi return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs, size); } +#ifdef PUGI_HAS_STRING_VIEW + PUGI_IMPL_FN bool xml_node::set_name(const string_view_t rhs) + { + return set_name(rhs.data(), rhd.size()); + } +#endif + PUGI_IMPL_FN bool xml_node::set_value(const char_t* rhs) { xml_node_type type_ = _root ? PUGI_IMPL_NODETYPE(_root) : node_null; @@ -5868,6 +5889,13 @@ namespace pugi return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs, size); } +#ifdef PUGI_HAS_STRING_VIEW + PUGI_IMPL_FN bool xml_node::set_value(const string_view_t rhs) + { + return set_value(rhs.data(), rhs.value()); + } +#endif + PUGI_IMPL_FN xml_attribute xml_node::append_attribute(const char_t* name_) { if (!impl::allow_insert_attribute(type())) return xml_attribute(); @@ -6757,6 +6785,13 @@ namespace pugi return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, size) : false; } +#ifdef PUGI_HAS_STRING_VIEW + PUGI_IMPL_FN bool xml_text::set(const string_view_t rhs) + { + return set(rhs.data(), rhs.size()); + } +#endif + PUGI_IMPL_FN bool xml_text::set(int rhs) { xml_node_struct* dn = _data_new(); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index b8d6b3c1..2eafe2b4 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -162,6 +162,7 @@ namespace pugi #endif #ifdef PUGI_HAS_STRING_VIEW + // String view type used for overloads of functions that accept strings; depends on PUGIXML_WCHAR_MODE using string_view_t = std::basic_string_view; #endif } @@ -447,8 +448,14 @@ namespace pugi // Set attribute name/value (returns false if attribute is empty or there is not enough memory) bool set_name(const char_t* rhs); bool set_name(const char_t* rhs, size_t size); +#ifdef PUGI_HAS_STRING_VIEW + bool set_name(string_view_t rhs); +#endif bool set_value(const char_t* rhs); bool set_value(const char_t* rhs, size_t size); +#ifdef PUGI_HAS_STRING_VIEW + bool set_value(string_view_t rhs); +#endif // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set_value(int rhs); @@ -583,8 +590,14 @@ namespace pugi // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) bool set_name(const char_t* rhs); bool set_name(const char_t* rhs, size_t size); +#ifdef PUGI_HAS_STRING_VIEW + bool set_name(string_view_t rhs); +#endif bool set_value(const char_t* rhs); bool set_value(const char_t* rhs, size_t size); +#ifdef PUGI_HAS_STRING_VIEW + bool set_value(string_view_t rhs); +#endif // Add attribute with specified name. Returns added attribute, or empty attribute on errors. xml_attribute append_attribute(const char_t* name); @@ -814,6 +827,9 @@ namespace pugi // Set text (returns false if object is empty or there is not enough memory) bool set(const char_t* rhs); bool set(const char_t* rhs, size_t size); +#ifdef PUGI_HAS_STRING_VIEW + bool set(string_view_t rhs); +#endif // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") bool set(int rhs); From bd0b8e6abeb9e514aa3844d7fd796c84f4219f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 20:56:23 +0200 Subject: [PATCH 04/11] Do not warn if string_view support is requested but not supported --- src/pugixml.hpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index 2eafe2b4..afd338fd 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -125,17 +125,13 @@ // Detect if C++ standard supports 'string_view' (2017 or higher) #ifndef PUGI_STRING_VIEW_SUPPORTED # if defined(__cpp_lib_string_view) || __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L -# define PUGI_STRING_VIEW_SUPPORTED 1 +# define PUGI_STRING_VIEW_SUPPORTED # endif #endif // Enable 'string_view' support if requested and supported #ifndef PUGI_HAS_STRING_VIEW -# if defined(PUGI_ENABLE_STRING_VIEW) && !defined(PUGIXML_NO_STL) -# ifdef PUGI_STRING_VIEW_SUPPORTED -# define PUGI_HAS_STRING_VIEW -# else -# warning "Support for std::string_view was requested but is not supported by your C++ standard" -# endif +# if defined(PUGI_STRING_VIEW_SUPPORTED) && defined(PUGI_ENABLE_STRING_VIEW) && !defined(PUGIXML_NO_STL) +# define PUGI_HAS_STRING_VIEW # endif #endif #ifdef PUGI_HAS_STRING_VIEW From 2f1be3b8cb2c07b8a7b04faee5160b18559d5118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 20:58:13 +0200 Subject: [PATCH 05/11] Replace type alias with typedef for consistency --- src/pugixml.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index afd338fd..edd2d804 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -159,7 +159,7 @@ namespace pugi #ifdef PUGI_HAS_STRING_VIEW // String view type used for overloads of functions that accept strings; depends on PUGIXML_WCHAR_MODE - using string_view_t = std::basic_string_view; + typedef std::basic_string_view string_view_t; #endif } From 3e7ecd2469f3ed632d8324fdb1ce0c916d028f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 21:18:28 +0200 Subject: [PATCH 06/11] Add commented out define of PUGIXML_STRING_VIEW to pugiconfig.hpp This allows to conveniently opt-in to support for std::string_view --- src/pugiconfig.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pugiconfig.hpp b/src/pugiconfig.hpp index a112de30..294e08c6 100644 --- a/src/pugiconfig.hpp +++ b/src/pugiconfig.hpp @@ -26,6 +26,11 @@ // Uncomment this to disable STL // #define PUGIXML_NO_STL +// Uncomment this to enable support for std::string_view (requires C++17, PUGIXML_NO_STL will override this) +// Note: In a future version of pugixml this macro will become obsolete. +// Support will then be enabled automatically if the used C++ standard supports it. +// #define PUGIXML_STRING_VIEW + // Uncomment this to disable exceptions // #define PUGIXML_NO_EXCEPTIONS From 71ad4932a224f6ab3b3ae309d8cf5c5d009a7837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 21:19:46 +0200 Subject: [PATCH 07/11] Clean up detection for string_view support No longer define PUGI_STRING_VIEW_SUPPORTED and replace PUGI_ENABLE_STRING_VIEW with PUGIXML_STRING_VIEW --- src/pugixml.hpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index edd2d804..c6ea59cd 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -122,15 +122,10 @@ # endif #endif -// Detect if C++ standard supports 'string_view' (2017 or higher) -#ifndef PUGI_STRING_VIEW_SUPPORTED -# if defined(__cpp_lib_string_view) || __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L -# define PUGI_STRING_VIEW_SUPPORTED -# endif -#endif -// Enable 'string_view' support if requested and supported +// Enable 'string_view' support if requested and supported (at least C++17) #ifndef PUGI_HAS_STRING_VIEW -# if defined(PUGI_STRING_VIEW_SUPPORTED) && defined(PUGI_ENABLE_STRING_VIEW) && !defined(PUGIXML_NO_STL) +# if (defined(__cpp_lib_string_view) || __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) \ + && defined(PUGIXML_STRING_VIEW) && !defined(PUGIXML_NO_STL) # define PUGI_HAS_STRING_VIEW # endif #endif @@ -1526,6 +1521,10 @@ namespace std # include PUGIXML_SOURCE #endif +#ifdef PUGI_HAS_STRING_VIEW +# undef PUGI_HAS_STRING_VIEW +#endif + /** * Copyright (c) 2006-2024 Arseny Kapoulkine * From db96936862c53bd152c580d272ea3f1615c70ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 21:54:22 +0200 Subject: [PATCH 08/11] Do not use __cpp_lib_string_view for detection of string_view support It is C++20 and likely needs to be conditionally included to be defined --- src/pugixml.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pugixml.hpp b/src/pugixml.hpp index c6ea59cd..b11e5d42 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -124,7 +124,7 @@ // Enable 'string_view' support if requested and supported (at least C++17) #ifndef PUGI_HAS_STRING_VIEW -# if (defined(__cpp_lib_string_view) || __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) \ +# if (__cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)) \ && defined(PUGIXML_STRING_VIEW) && !defined(PUGIXML_NO_STL) # define PUGI_HAS_STRING_VIEW # endif From 16eb5dabff6484de4525f6e812aca846824d2ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 21:57:34 +0200 Subject: [PATCH 09/11] Do not const qualify by-value arguments --- src/pugixml.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 8fa592ef..ebd472ce 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -5442,7 +5442,7 @@ namespace pugi } #ifdef PUGI_HAS_STRING_VIEW - PUGI_IMPL_FN bool xml_attribute::set_name(const string_view_t rhs) + PUGI_IMPL_FN bool xml_attribute::set_name(string_view_t rhs) { return set_name(rhs.data(), rhs.size()); } @@ -5463,7 +5463,7 @@ namespace pugi } #ifdef PUGI_HAS_STRING_VIEW - PUGI_IMPL_FN bool xml_attribute::set_value(const string_view_t rhs) + PUGI_IMPL_FN bool xml_attribute::set_value(string_view_t rhs) { return set_value(rhs.data(), rhs.size()); } @@ -5863,7 +5863,7 @@ namespace pugi } #ifdef PUGI_HAS_STRING_VIEW - PUGI_IMPL_FN bool xml_node::set_name(const string_view_t rhs) + PUGI_IMPL_FN bool xml_node::set_name(string_view_t rhs) { return set_name(rhs.data(), rhd.size()); } @@ -5890,7 +5890,7 @@ namespace pugi } #ifdef PUGI_HAS_STRING_VIEW - PUGI_IMPL_FN bool xml_node::set_value(const string_view_t rhs) + PUGI_IMPL_FN bool xml_node::set_value(string_view_t rhs) { return set_value(rhs.data(), rhs.value()); } @@ -6786,7 +6786,7 @@ namespace pugi } #ifdef PUGI_HAS_STRING_VIEW - PUGI_IMPL_FN bool xml_text::set(const string_view_t rhs) + PUGI_IMPL_FN bool xml_text::set(string_view_t rhs) { return set(rhs.data(), rhs.size()); } From e9da0a663fba6fa2c9f4ba421f267e92e7e21384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 22:38:23 +0200 Subject: [PATCH 10/11] Add possibility to pass additional CXXFLAGS to makefile as pugiflags --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 41a92ae8..a0d68a0a 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ MAKEFLAGS+=-r config=debug defines=standard cxxstd=c++11 +pugiflags= # set cxxstd=any to disable use of -std=... BUILD=build/make-$(firstword $(CXX))-$(config)-$(defines)-$(cxxstd) @@ -40,6 +41,10 @@ ifneq ($(defines),standard) CXXFLAGS+=-D $(subst $(COMMA), -D ,$(defines)) endif +ifneq ($(pugiflags),) + CXXFLAGS+=$(pugiflags) +endif + ifneq ($(findstring PUGIXML_NO_EXCEPTIONS,$(defines)),) CXXFLAGS+=-fno-exceptions endif From d7c5eeed4fdea0389647770803f82599ab1bdc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matth=C3=A4us=20Brandl?= Date: Fri, 13 Sep 2024 22:40:29 +0200 Subject: [PATCH 11/11] Enable PUGIXML_STRING_VIEW when building tests --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf6948b8..96c6290b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,6 +23,7 @@ jobs: - name: make test run: | export CXX=${{matrix.compiler}} + make test cxxstd=c++17 defines=${{matrix.defines}} config=release pugiflags=-DPUGIXML_STRING_VIEW -j2 make test cxxstd=c++11 defines=${{matrix.defines}} config=release -j2 make test cxxstd=c++98 defines=${{matrix.defines}} config=debug -j2 make test defines=${{matrix.defines}} config=sanitize -j2 @@ -42,7 +43,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: cmake configure - run: cmake . -DPUGIXML_BUILD_TESTS=ON -D${{matrix.defines}}=ON -A ${{matrix.arch}} + run: cmake . -DPUGIXML_BUILD_TESTS=ON -D${{matrix.defines}}=ON -DPUGIXML_STRING_VIEW=ON -A ${{matrix.arch}} - name: cmake test shell: bash # necessary for fail-fast run: |