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
This commit is contained in:
Mark Olesen
2025-03-11 14:01:59 +01:00
parent 36ae93d017
commit 38e08fc092
7 changed files with 103 additions and 82 deletions

View File

@ -1,3 +1,3 @@
Test-stringSplit.C Test-stringSplit.cxx
EXE = $(FOAM_USER_APPBIN)/Test-stringSplit EXE = $(FOAM_USER_APPBIN)/Test-stringSplit

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -50,11 +50,12 @@ void printSubStrings
<< split.size() << " elements {" << split.length() << " chars}" << split.size() << " elements {" << split.length() << " chars}"
<< nl; << nl;
unsigned i = 0; for (unsigned i = 0; i < split.size(); ++i)
for (const auto s : split)
{ {
Info<< "[" << i++ << "] {" << s.length() << " chars} = " const auto& s = split[i];
<< s.str() << nl; Info<< "[" << i << "] {" << s.length() << " chars} = "
<< split.view(i) << " == " << s.str()
<< nl;
} }
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,11 +32,6 @@ License
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
static std::unique_ptr<Foam::ITstream> emptyStreamPtr_;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -74,20 +69,22 @@ static label parseStream(ISstream& is, tokenList& tokens)
Foam::ITstream& Foam::ITstream::empty_stream() Foam::ITstream& Foam::ITstream::empty_stream()
{ {
if (emptyStreamPtr_) static std::unique_ptr<ITstream> singleton;
if (!singleton)
{ {
emptyStreamPtr_->ITstream::clear(); // Ensure it really is empty singleton = std::make_unique<ITstream>(Foam::zero{}, "empty-stream");
emptyStreamPtr_->ITstream::seek(0); // rewind() bypassing virtual
} }
else 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 // Set stream as bad - indicates it is not a valid stream
emptyStreamPtr_->setBad(); singleton->setBad();
return *emptyStreamPtr_; return *singleton;
} }
@ -186,7 +183,7 @@ Foam::ITstream::ITstream
Foam::ITstream::ITstream Foam::ITstream::ITstream
( (
const Foam::zero, Foam::zero,
const string& name, const string& name,
IOstreamOption streamOpt 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 Foam::ITstream::ITstream
( (
const char* input, const char* input,

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -122,7 +122,7 @@ public:
//- Construct empty, optionally with given name //- Construct empty, optionally with given name
explicit ITstream explicit ITstream
( (
const Foam::zero, Foam::zero,
const string& name = "input", const string& name = "input",
IOstreamOption streamOpt = IOstreamOption() IOstreamOption streamOpt = IOstreamOption()
); );
@ -152,15 +152,6 @@ public:
const string& name = "input" 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 //- Construct token list by parsing the input character sequence
// Uses static parse function internally. // Uses static parse function internally.
explicit ITstream explicit ITstream
@ -170,20 +161,23 @@ public:
const string& name = "input" const string& name = "input"
); );
#if __cplusplus >= 201703L
//- Construct token list by parsing the input character sequence //- Construct token list by parsing the input character sequence
// Uses static parse function internally. // Uses static parse function internally.
explicit ITstream explicit ITstream
( (
#if __cplusplus >= 201703L
std::string_view s, 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()); reset(s.data(), s.size());
} }
#endif
//- Construct token list by parsing the input character sequence //- Construct token list by parsing the input character sequence
// Uses static parse function internally. // Uses static parse function internally.

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2024 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -202,13 +202,28 @@ public:
stream_type::clear(); // Clear old errors 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<char>::length(s) : 0));
}
//- Reset the get buffer area to use the data from a string //- Reset the get buffer area to use the data from a string
void reset(const std::string& s) void reset(const std::string& s)
{ {
buffer_type::resetg(const_cast<char*>(&s[0]), s.size()); buffer_type::resetg(const_cast<char*>(s.data()), s.size());
stream_type::clear(); // Clear old errors 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<char*>(s.data()), s.size());
stream_type::clear(); // Clear old errors
}
#endif
//- Some information about the input buffer position/capacity //- Some information about the input buffer position/capacity
void debug_info(Ostream& os) const void debug_info(Ostream& os) const
{ {
@ -257,17 +272,37 @@ public:
reset(buffer, nbytes); reset(buffer, nbytes);
} }
//- Construct using specified nul-terminated buffer
explicit ISpanStream(const char* buffer)
:
ISpanStream
(
buffer,
(buffer ? std::char_traits<char>::length(buffer) : 0)
)
{}
//- Use data area from string content //- Use data area from string content
explicit ISpanStream explicit ISpanStream
( (
const std::string& buffer, const std::string& s,
IOstreamOption streamOpt = IOstreamOption() IOstreamOption streamOpt = IOstreamOption()
) )
: :
ISpanStream(streamOpt) ISpanStream(s.data(), s.size(), streamOpt)
{ {}
reset(buffer);
} #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 //- Construct using data area from a List and its inherent storage size
// Uses addressed size, thus no special treatment for a DynamicList // Uses addressed size, thus no special treatment for a DynamicList
@ -280,18 +315,6 @@ public:
ISpanStream(buffer.cdata(), buffer.size(), streamOpt) 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 //- Construct (shallow copy) from span character content
explicit ISpanStream explicit ISpanStream
( (
@ -357,7 +380,7 @@ public:
//- Reset input area to use data from a string //- Reset input area to use data from a string
void reset(const std::string& s) void reset(const std::string& s)
{ {
stream_.reset(s); stream_.reset(s.data(), s.size());
syncState(); syncState();
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2024 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -197,7 +197,7 @@ public:
void reset(std::string& s) void reset(std::string& s)
{ {
s.resize(s.capacity()); 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 stream_type::clear(); // Clear any old errors
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,6 +36,7 @@ Description
#define Foam_SubStrings_H #define Foam_SubStrings_H
#include <regex> // For std::sub_match #include <regex> // For std::sub_match
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -82,12 +83,40 @@ public:
return len; 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. //- Retrieve element at pos, converted to a string type.
StringType str(size_t pos) const StringType str(size_t pos) const
{ {
return (*this)[pos].str(); 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<const char*>::pointer_to(*(s.first)),
(s.second - s.first)
);
#endif
}
#endif /* __cplusplus >= 201703L */
//- Append sub-string defined by begin/end iterators //- Append sub-string defined by begin/end iterators
void append void append
( (
@ -135,16 +164,6 @@ public:
this->resize(this->size() - n); this->resize(this->size() - n);
} }
} }
// FUTURE?
// #if __cplusplus >= 201703L
// std::string_view view(size_t pos) const
// {}
// #else
// stdFoam::span<const char> view(size_t pos) const
// {}
// #endif
}; };