From 38e08fc09279f17576b46dcce3f692dd1eed2c4e Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 11 Mar 2025 14:01:59 +0100 Subject: [PATCH] COMP: avoid constructor ambiguity for ISpanStream - compiler cannot decide between std::string and std::string_view when creating from 'const char*' without also supplying the size, so also supply a 'const char*' constructor. ENH: additional string_view handling for ITstream and SubStrings --- applications/test/stringSplit/Make/files | 2 +- ...est-stringSplit.C => Test-stringSplit.cxx} | 11 ++-- src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C | 38 ++++------- src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H | 24 +++---- .../db/IOstreams/memory/ISpanStream.H | 63 +++++++++++++------ .../db/IOstreams/memory/OSpanStream.H | 4 +- .../primitives/strings/lists/SubStrings.H | 43 +++++++++---- 7 files changed, 103 insertions(+), 82 deletions(-) rename applications/test/stringSplit/{Test-stringSplit.C => Test-stringSplit.cxx} (96%) diff --git a/applications/test/stringSplit/Make/files b/applications/test/stringSplit/Make/files index 06bdafe1b2..93be033269 100644 --- a/applications/test/stringSplit/Make/files +++ b/applications/test/stringSplit/Make/files @@ -1,3 +1,3 @@ -Test-stringSplit.C +Test-stringSplit.cxx EXE = $(FOAM_USER_APPBIN)/Test-stringSplit diff --git a/applications/test/stringSplit/Test-stringSplit.C b/applications/test/stringSplit/Test-stringSplit.cxx similarity index 96% rename from applications/test/stringSplit/Test-stringSplit.C rename to applications/test/stringSplit/Test-stringSplit.cxx index bc12f4b166..14d4cab890 100644 --- a/applications/test/stringSplit/Test-stringSplit.C +++ b/applications/test/stringSplit/Test-stringSplit.cxx @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2024 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -50,11 +50,12 @@ void printSubStrings << split.size() << " elements {" << split.length() << " chars}" << nl; - unsigned i = 0; - for (const auto s : split) + for (unsigned i = 0; i < split.size(); ++i) { - Info<< "[" << i++ << "] {" << s.length() << " chars} = " - << s.str() << nl; + const auto& s = split[i]; + Info<< "[" << i << "] {" << s.length() << " chars} = " + << split.view(i) << " == " << s.str() + << nl; } } diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C index 66c2125e83..22f0ca99f9 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2017-2024 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,11 +32,6 @@ License #include #include -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -static std::unique_ptr emptyStreamPtr_; - - // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // namespace Foam @@ -74,20 +69,22 @@ static label parseStream(ISstream& is, tokenList& tokens) Foam::ITstream& Foam::ITstream::empty_stream() { - if (emptyStreamPtr_) + static std::unique_ptr singleton; + + if (!singleton) { - emptyStreamPtr_->ITstream::clear(); // Ensure it really is empty - emptyStreamPtr_->ITstream::seek(0); // rewind() bypassing virtual + singleton = std::make_unique(Foam::zero{}, "empty-stream"); } else { - emptyStreamPtr_.reset(new ITstream(Foam::zero{}, "empty-stream")); + singleton->ITstream::clear(); // Ensure it really is empty + singleton->ITstream::seek(0); // rewind() bypassing virtual } - // Set stream as bad to indicate that this is an invald stream - emptyStreamPtr_->setBad(); + // Set stream as bad - indicates it is not a valid stream + singleton->setBad(); - return *emptyStreamPtr_; + return *singleton; } @@ -186,7 +183,7 @@ Foam::ITstream::ITstream Foam::ITstream::ITstream ( - const Foam::zero, + Foam::zero, const string& name, IOstreamOption streamOpt ) @@ -242,19 +239,6 @@ Foam::ITstream::ITstream } -Foam::ITstream::ITstream -( - const std::string& input, - IOstreamOption streamOpt, - const string& name -) -: - ITstream(streamOpt, name) -{ - reset(input.data(), input.size()); -} - - Foam::ITstream::ITstream ( const char* input, diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H index 37e5571e8d..7d3157a3b6 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2017-2024 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -122,7 +122,7 @@ public: //- Construct empty, optionally with given name explicit ITstream ( - const Foam::zero, + Foam::zero, const string& name = "input", IOstreamOption streamOpt = IOstreamOption() ); @@ -152,15 +152,6 @@ public: const string& name = "input" ); - //- Construct token list by parsing the input string - // Uses static parse function internally. - explicit ITstream - ( - const std::string& input, - IOstreamOption streamOpt = IOstreamOption(), - const string& name = "input" - ); - //- Construct token list by parsing the input character sequence // Uses static parse function internally. explicit ITstream @@ -170,20 +161,23 @@ public: const string& name = "input" ); - #if __cplusplus >= 201703L //- Construct token list by parsing the input character sequence // Uses static parse function internally. explicit ITstream ( + #if __cplusplus >= 201703L std::string_view s, - IOstreamOption streamOpt = IOstreamOption() + #else + const std::string& s, + #endif + IOstreamOption streamOpt = IOstreamOption(), + const string& name = "input" ) : - ITstream(streamOpt) + ITstream(streamOpt, name) { reset(s.data(), s.size()); } - #endif //- Construct token list by parsing the input character sequence // Uses static parse function internally. diff --git a/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H b/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H index d1d259b193..3d0b7e5738 100644 --- a/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2024 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -202,13 +202,28 @@ public: stream_type::clear(); // Clear old errors } + //- Reset the get buffer area to use the nul-terminated buffer + void reset(const char* s) + { + reset(s, (s ? std::char_traits::length(s) : 0)); + } + //- Reset the get buffer area to use the data from a string void reset(const std::string& s) { - buffer_type::resetg(const_cast(&s[0]), s.size()); + buffer_type::resetg(const_cast(s.data()), s.size()); stream_type::clear(); // Clear old errors } + #if __cplusplus >= 201703L + //- Reset the get buffer area to use the data from a string_view + void reset(std::string_view s) + { + buffer_type::resetg(const_cast(s.data()), s.size()); + stream_type::clear(); // Clear old errors + } + #endif + //- Some information about the input buffer position/capacity void debug_info(Ostream& os) const { @@ -257,17 +272,37 @@ public: reset(buffer, nbytes); } + //- Construct using specified nul-terminated buffer + explicit ISpanStream(const char* buffer) + : + ISpanStream + ( + buffer, + (buffer ? std::char_traits::length(buffer) : 0) + ) + {} + //- Use data area from string content explicit ISpanStream ( - const std::string& buffer, + const std::string& s, IOstreamOption streamOpt = IOstreamOption() ) : - ISpanStream(streamOpt) - { - reset(buffer); - } + ISpanStream(s.data(), s.size(), streamOpt) + {} + + #if __cplusplus >= 201703L + //- Use data area from string_view content + explicit ISpanStream + ( + std::string_view s, + IOstreamOption streamOpt = IOstreamOption() + ) + : + ISpanStream(s.data(), s.size(), streamOpt) + {} + #endif //- Construct using data area from a List and its inherent storage size // Uses addressed size, thus no special treatment for a DynamicList @@ -280,18 +315,6 @@ public: ISpanStream(buffer.cdata(), buffer.size(), streamOpt) {} - #if __cplusplus >= 201703L - //- Construct (shallow copy) from std::string_view content - explicit ISpanStream - ( - std::string_view s, - IOstreamOption streamOpt = IOstreamOption() - ) - : - ISpanStream(s.data(), s.size(), streamOpt) - {} - #endif - //- Construct (shallow copy) from span character content explicit ISpanStream ( @@ -357,7 +380,7 @@ public: //- Reset input area to use data from a string void reset(const std::string& s) { - stream_.reset(s); + stream_.reset(s.data(), s.size()); syncState(); } diff --git a/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H b/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H index 58cf0e0b39..4da824f41a 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2024 OpenCFD Ltd. + Copyright (C) 2016-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -197,7 +197,7 @@ public: void reset(std::string& s) { s.resize(s.capacity()); - buffer_type::resetp(&s[0], s.size()); + buffer_type::resetp(s.data(), s.size()); stream_type::clear(); // Clear any old errors } diff --git a/src/OpenFOAM/primitives/strings/lists/SubStrings.H b/src/OpenFOAM/primitives/strings/lists/SubStrings.H index 373bebb6d4..4e97f6b90c 100644 --- a/src/OpenFOAM/primitives/strings/lists/SubStrings.H +++ b/src/OpenFOAM/primitives/strings/lists/SubStrings.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2024 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,7 +35,8 @@ Description #ifndef Foam_SubStrings_H #define Foam_SubStrings_H -#include // For std::sub_match +#include // For std::sub_match +#include #include #include @@ -82,12 +83,40 @@ public: return len; } + //- Return length of element at pos + std::string::size_type length(size_t pos) const + { + return (*this)[pos].length(); + } + //- Retrieve element at pos, converted to a string type. StringType str(size_t pos) const { return (*this)[pos].str(); } + #if __cplusplus >= 201703L + //- Return element at pos as a string_view + std::string_view view(size_t pos) const + { + #if __cplusplus >= 202002L + return std::string_view + ( + (*this)[pos].first, + (*this)[pos].second + ); + #else + // No string_view construct from iterator pairs before c++20 + const auto& s = (*this)[pos]; + return std::string_view + ( + std::pointer_traits::pointer_to(*(s.first)), + (s.second - s.first) + ); + #endif + } + #endif /* __cplusplus >= 201703L */ + //- Append sub-string defined by begin/end iterators void append ( @@ -135,16 +164,6 @@ public: this->resize(this->size() - n); } } - - - // FUTURE? - // #if __cplusplus >= 201703L - // std::string_view view(size_t pos) const - // {} - // #else - // stdFoam::span view(size_t pos) const - // {} - // #endif };