ENH: simplify SubStrings class/handling (remove template parameters)

- previous code used derived string iterators, but these would
  be largely ignored anyhow since the underlying std::sub_match
  str() method would just yields a std::string anyhow.

  The SubStrings::str(size_t) method wasn't used in any code, so now
  just use std::string iterators only.

  This change simplfies overall handling, since it removes an unneeded
  template dependency.
This commit is contained in:
Mark Olesen
2025-03-28 16:25:18 +01:00
parent bdac68ebc7
commit e720f823d3
37 changed files with 341 additions and 348 deletions

View File

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

View File

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

View File

@ -89,7 +89,7 @@ int main(int argc, char *argv[])
inputType in1("move-construct-from"); inputType in1("move-construct-from");
Info<<"move construct from " << in1.length() << nl; Info<<"move construct from " << in1.size() << nl;
outputType out1(std::move(in1)); outputType out1(std::move(in1));
@ -100,7 +100,7 @@ int main(int argc, char *argv[])
out1 = "some-text-rubbish"; out1 = "some-text-rubbish";
out1.resize(10); out1.resize(10);
Info<<"move assign from " << in1.length() << nl; Info<<"move assign from " << in1.size() << nl;
out1 = std::move(in1); out1 = std::move(in1);
@ -329,7 +329,7 @@ int main(int argc, char *argv[])
string s2(s.expand()); string s2(s.expand());
cout<< "output string with " << s2.length() << " characters\n"; cout<< "output string with " << s2.size() << " characters\n";
cout<< "ostream<< >" << s2 << "<\n"; cout<< "ostream<< >" << s2 << "<\n";
Info<< "Ostream<< >" << s2 << "<\n"; Info<< "Ostream<< >" << s2 << "<\n";
Info<< "hash:" << hex << string::hasher()(s2) << dec << endl; Info<< "hash:" << hex << string::hasher()(s2) << dec << endl;

View File

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

View File

@ -43,7 +43,7 @@ template<class StringType>
void printSubStrings void printSubStrings
( (
const StringType& str, const StringType& str,
const SubStrings<StringType>& split const SubStrings& split
) )
{ {
Info<< "string {" << str.size() << " chars} = " << str << nl Info<< "string {" << str.size() << " chars} = " << str << nl

View File

@ -645,7 +645,7 @@ bool Foam::fileFormats::ensightMeshReader::readGeometry
// Parse all // Parse all
SubStrings<string> split; SubStrings split;
while (is.good()) while (is.good())
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -37,7 +37,7 @@ Description
#include "argList.H" #include "argList.H"
#include "OFstream.H" #include "OFstream.H"
#include "StringStream.H" #include "stringOps.H"
#include "point.H" #include "point.H"
#include "DynamicList.H" #include "DynamicList.H"
@ -58,58 +58,49 @@ string getLine(std::ifstream& is)
} }
// Read space-separated vertices (with optional '/' arguments) // Token list with one of the following:
labelList parseVertices(const string& line) // f v1 v2 v3 ...
// f v1/vt1 v2/vt2 v3/vt3 ...
// l v1 v2 v3 ...
// l v1/vt1 v2/vt2 v3/vt3 ...
static label readObjVertices
(
const SubStrings& tokens,
DynamicList<label>& verts
)
{ {
DynamicList<label> verts; verts.clear();
// Assume 'l' is followed by space. bool first = true;
string::size_type endNum = 1; for (const auto& tok : tokens)
do
{ {
string::size_type startNum = line.find_first_not_of(' ', endNum); if (first)
if (startNum == string::npos)
{ {
break; // skip initial "f" or "l"
first = false;
continue;
} }
endNum = line.find(' ', startNum); std::string vrtSpec(tok.str());
string vertexSpec; if
if (endNum != string::npos) (
const auto slash = vrtSpec.find('/');
slash != std::string::npos
)
{ {
vertexSpec = line.substr(startNum, endNum-startNum); vrtSpec.erase(slash);
}
else
{
vertexSpec = line.substr(startNum, line.size() - startNum);
} }
string::size_type slashPos = vertexSpec.find('/'); label vertId = readLabel(vrtSpec);
label vertI = 0; verts.push_back(vertId - 1);
if (slashPos != string::npos)
{
IStringStream intStream(vertexSpec.substr(0, slashPos));
intStream >> vertI;
} }
else
{
IStringStream intStream(vertexSpec);
intStream >> vertI; return verts.size();
}
verts.append(vertI - 1);
}
while (true);
return verts.shrink();
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -142,6 +133,8 @@ int main(int argc, char *argv[])
DynamicList<labelList> polyLines; DynamicList<labelList> polyLines;
DynamicList<labelList> polygons; DynamicList<labelList> polygons;
DynamicList<label> dynVerts;
bool hasWarned = false; bool hasWarned = false;
label lineNo = 0; label lineNo = 0;
@ -152,33 +145,58 @@ int main(int argc, char *argv[])
if (line.empty()) continue; if (line.empty()) continue;
// Read first word const auto tokens = stringOps::splitSpace(line);
IStringStream lineStream(line);
word cmd(lineStream); // Require command and some arguments
if (tokens.size() < 2)
{
continue;
}
const word cmd = word::validate(tokens[0]);
if (cmd == "v") if (cmd == "v")
{ {
scalar x, y, z; // Vertex
// v x y z
lineStream >> x >> y >> z; points.emplace_back
(
points.append(point(x, y, z)); readScalar(tokens[1]),
readScalar(tokens[2]),
readScalar(tokens[3])
);
} }
else if (cmd == "vn") else if (cmd == "vn")
{ {
scalar x, y, z; // Vertex normals
// vn x y z
lineStream >> x >> y >> z; pointNormals.emplace_back
(
pointNormals.append(vector(x, y, z)); readScalar(tokens[1]),
readScalar(tokens[2]),
readScalar(tokens[3])
);
} }
else if (cmd == "l") else if (cmd == "l")
{ {
polyLines.append(parseVertices(line)); // Line
// l v1 v2 v3 ...
// OR
// l v1/vt1 v2/vt2 v3/vt3 ...
readObjVertices(tokens, dynVerts);
polyLines.emplace_back() = dynVerts;
} }
else if (cmd == "f") else if (cmd == "f")
{ {
polygons.append(parseVertices(line)); // f v1 v2 v3 ...
// OR
// f v1/vt1 v2/vt2 v3/vt3 ...
readObjVertices(tokens, dynVerts);
polygons.emplace_back() = dynVerts;
} }
else if (cmd != "") else if (cmd != "")
{ {
@ -188,7 +206,7 @@ int main(int argc, char *argv[])
WarningInFunction WarningInFunction
<< "Unrecognized OBJ command " << cmd << nl << "Unrecognized OBJ command " << cmd << nl
<< "In line " << lineStream.str() << "In line " << line
<< " at linenumber " << lineNo << nl << " at linenumber " << lineNo << nl
<< "Only recognized commands are 'v' and 'l'.\n" << "Only recognized commands are 'v' and 'l'.\n"
<< "If this is a surface command use surfaceConvert instead" << "If this is a surface command use surfaceConvert instead"
@ -230,46 +248,42 @@ int main(int argc, char *argv[])
} }
label nItems = 0; label nItems = 0;
forAll(polyLines, polyI) for (const labelList& line : polyLines)
{ {
nItems += polyLines[polyI].size() + 1; nItems += line.size() + 1;
} }
outFile outFile
<< "LINES " << polyLines.size() << ' ' << nItems << nl; << "LINES " << polyLines.size() << ' ' << nItems << nl;
forAll(polyLines, polyI) for (const labelList& line : polyLines)
{ {
const labelList& line = polyLines[polyI];
outFile << line.size(); outFile << line.size();
forAll(line, i) for (const label vrt : line)
{ {
outFile << ' ' << line[i]; outFile << ' ' << vrt;
} }
outFile << nl; outFile << nl;
} }
nItems = 0; nItems = 0;
forAll(polygons, polyI) for (const labelList& line : polygons)
{ {
nItems += polygons[polyI].size() + 1; nItems += line.size() + 1;
} }
outFile outFile
<< "POLYGONS " << polygons.size() << ' ' << nItems << nl; << "POLYGONS " << polygons.size() << ' ' << nItems << nl;
forAll(polygons, polyI) for (const labelList& line : polygons)
{ {
const labelList& line = polygons[polyI];
outFile << line.size(); outFile << line.size();
forAll(line, i) for (const label vrt : line)
{ {
outFile << ' ' << line[i]; outFile << ' ' << vrt;
} }
outFile << nl; outFile << nl;
} }

View File

@ -119,6 +119,8 @@ static inline void* loadLibrary(const Foam::fileName& libName)
constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL); constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
#ifdef __APPLE__ #ifdef __APPLE__
using namespace Foam;
const char* normal = nullptr; const char* normal = nullptr;
const char* shadow = nullptr; const char* shadow = nullptr;
@ -132,8 +134,8 @@ static inline void* loadLibrary(const Foam::fileName& libName)
// SIP appears to have cleared DYLD_LIBRARY_PATH but the // SIP appears to have cleared DYLD_LIBRARY_PATH but the
// shadow parameter is available // shadow parameter is available
const Foam::string ldPaths(shadow); const std::string ldPaths(shadow);
const auto paths = Foam::stringOps::split<Foam::string>(ldPaths, ':'); const auto paths = Foam::stringOps::split(ldPaths, ':');
for (const auto& p : paths) for (const auto& p : paths)
{ {

View File

@ -158,14 +158,15 @@ $(strings)/keyType/keyType.C
$(strings)/regex/regExpCxx.C $(strings)/regex/regExpCxx.C
$(strings)/wordRe/wordRe.C $(strings)/wordRe/wordRe.C
$(strings)/wordRes/wordRes.C $(strings)/wordRes/wordRes.C
$(strings)/lists/CStringList.C $(strings)/lists/CStringList.cxx
$(strings)/lists/hashedWordList.C $(strings)/lists/hashedWordList.cxx
$(strings)/parsing/parsing.C $(strings)/parsing/parsing.C
$(strings)/parsing/genericRagelLemonDriver.C $(strings)/parsing/genericRagelLemonDriver.C
$(strings)/stringOps/stringOps.C $(strings)/stringOps/stringOps.cxx
$(strings)/stringOps/stringOpsEvaluate.C $(strings)/stringOps/stringOpsEvaluate.cxx
$(strings)/stringOps/stringOpsSort.C $(strings)/stringOps/stringOpsSort.cxx
$(strings)/stringOps/stringOpsSplit.C $(strings)/stringOps/stringOpsSplit.cxx
$(strings)/stringOps/stringOpsSubstr.cxx
expr = expressions expr = expressions
$(expr)/exprEntry/expressionEntry.C $(expr)/exprEntry/expressionEntry.C

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -192,8 +192,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchSlashScoped
} }
} }
// Split on '/' auto cmpts = stringOps::split(keyword, '/');
auto cmpts = stringOps::split<std::string>(keyword, '/');
auto remaining = cmpts.size(); auto remaining = cmpts.size();
for (const auto& cmpt : cmpts) for (const auto& cmpt : cmpts)
@ -397,7 +396,7 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDict
fileName path(dictPath); // Work on copy fileName path(dictPath); // Work on copy
path.clean(); // Remove unneeded ".." path.clean(); // Remove unneeded ".."
auto dictCmpts = stringOps::split(path, '/'); // Split on '/' auto dictCmpts = stringOps::split(path, '/');
for (const auto& cmpt : dictCmpts) for (const auto& cmpt : dictCmpts)
{ {
@ -502,7 +501,7 @@ Foam::dictionary* Foam::dictionary::makeScopedDict(const fileName& dictPath)
std::string path(dictPath); // Work on a copy std::string path(dictPath); // Work on a copy
fileName::clean(path); // Remove unneeded ".." fileName::clean(path); // Remove unneeded ".."
auto dictCmpts = stringOps::split(path, '/'); // Split on '/' auto dictCmpts = stringOps::split(path, '/');
for (const auto& cmpt : dictCmpts) for (const auto& cmpt : dictCmpts)
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2010-2018 Bernhard Gschaider Copyright (C) 2010-2018 Bernhard Gschaider
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -387,8 +387,7 @@ void Foam::expressions::exprDriver::addVariables
} }
// Allow inline list of semicolon-separated variables // Allow inline list of semicolon-separated variables
const auto varExpressions = const auto varExpressions = stringOps::split(expr, ';');
stringOps::split<expressions::exprString>(expr, ';');
for (const auto& subMatch : varExpressions) for (const auto& subMatch : varExpressions)
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,7 +59,7 @@ static List<expressions::exprString> expandExprStrings
for (const string& input : inputs) for (const string& input : inputs)
{ {
// Allow inline list of semicolon-separated variables // Allow inline list of semicolon-separated variables
const auto varExpressions = stringOps::split<string>(input, ';'); const auto varExpressions = stringOps::split(input, ';');
for (const auto& subMatch : varExpressions) for (const auto& subMatch : varExpressions)
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -538,7 +538,7 @@ Foam::fileName Foam::fileName::relative
Foam::wordList Foam::fileName::components(const char delim) const Foam::wordList Foam::fileName::components(const char delim) const
{ {
const auto parsed = stringOps::split<string>(*this, delim); const auto parsed = stringOps::split(*this, delim);
wordList words(parsed.size()); wordList words(parsed.size());
@ -561,7 +561,7 @@ Foam::word Foam::fileName::component
const char delim const char delim
) const ) const
{ {
const auto parsed = stringOps::split<string>(*this, delim); const auto parsed = stringOps::split(*this, delim);
if (parsed.size()) if (parsed.size())
{ {

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.
@ -54,6 +54,7 @@ Description
#include "fileNameList.H" #include "fileNameList.H"
#include "stringList.H" #include "stringList.H"
#include "wordList.H" #include "wordList.H"
#include "SubStrings.H"
#include <algorithm> // std::copy #include <algorithm> // std::copy
#include <utility> // std::initializer_list #include <utility> // std::initializer_list
@ -63,9 +64,6 @@ Description
namespace Foam namespace Foam
{ {
// Forward Declarations
template<class StringType> class SubStrings;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class CStringList Declaration Class CStringList Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -137,8 +135,7 @@ public:
//- Copy construct from a list of sub-string references //- Copy construct from a list of sub-string references
// Copies the input characters. // Copies the input characters.
template<class StringType> explicit CStringList(const SubStrings& input);
inline explicit CStringList(const SubStrings<StringType>& input);
//- Destructor. Invokes clear() to free memory. //- Destructor. Invokes clear() to free memory.
@ -155,10 +152,10 @@ public:
// Access // Access
//- True if the size (ie, argc) is zero. //- True if the size (ie, argc) is zero.
inline bool empty() const noexcept; bool empty() const noexcept { return !argc_; }
//- Return the number of C-strings (ie, argc) //- Return the number of C-strings (ie, argc)
inline int size() const noexcept; int size() const noexcept { return argc_; }
//- The flattened character content, with interspersed nul-chars //- The flattened character content, with interspersed nul-chars
const char* cdata_bytes() const noexcept { return data_; } const char* cdata_bytes() const noexcept { return data_; }
@ -174,11 +171,11 @@ public:
size_t length() const noexcept { return nbytes_; } size_t length() const noexcept { return nbytes_; }
//- Return string element at the given index. No bounds checking. //- Return string element at the given index. No bounds checking.
const char* get(int i) const; const char* get(int i) const { return argv_[i]; }
//- Return the list of C-strings (ie, argv) //- Return the list of C-strings (ie, argv)
// The position at argc is a nullptr // The position at argc is a nullptr
inline char** strings() const noexcept; char** strings() const noexcept { return argv_; }
//- Return the sublist of C-strings (ie, argv) starting at the //- Return the sublist of C-strings (ie, argv) starting at the
//- specified offset. //- specified offset.
@ -198,31 +195,36 @@ public:
//- Copy the input list of strings. //- Copy the input list of strings.
// \return number of arguments (argc) // \return number of arguments (argc)
template<class StringType> template<class StringType>
inline int reset(const UList<StringType>& input); int reset(const UList<StringType>& input)
{
return resetContent(input);
}
//- Copy the input list of strings. //- Copy the input list of strings.
// \return number of arguments (argc) // \return number of arguments (argc)
template<class StringType> int reset(const SubStrings& input)
inline int reset(const SubStrings<StringType>& input); {
return resetContent(input);
}
// Other // Other
//- Create a list from argc/argv parameters. //- Create a list from argc/argv parameters.
// A null pointer for argv is permissible when argc is zero. // A null pointer for argv is permissible when argc is zero.
template<class StringType> template<class StringType = std::string>
static List<StringType> asList(int argc, const char * const argv[]); static List<StringType> asList(int argc, const char * const argv[]);
//- Create a list from a nullptr-terminated list of argv parameters. //- Create a list from a nullptr-terminated list of argv parameters.
// Using a nullptr for argv is permissible. // Using a nullptr for argv is permissible.
template<class StringType> template<class StringType = std::string>
static inline List<StringType> asList(const char * const argv[]); static inline List<StringType> asList(const char * const argv[]);
// Member Operators // Member Operators
//- Return element at the given index. No bounds checking. //- Return element at the given index. No bounds checking.
inline const char* operator[](int i) const; const char* operator[](int i) const { return argv_[i]; }
}; };
@ -241,7 +243,7 @@ Ostream& operator<<(Ostream& os, const CStringList& list);
#include "CStringListI.H" #include "CStringListI.H"
#ifdef NoRepository #ifdef NoRepository
# include "CStringListTemplates.C" # include "CStringList.txx"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,8 +28,19 @@ License
#include "CStringList.H" #include "CStringList.H"
#include "Ostream.H" #include "Ostream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::CStringList::CStringList(const SubStrings& input)
:
CStringList()
{
resetContent(input);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Largely identical to resetContent() except with 'c-string'
int Foam::CStringList::reset int Foam::CStringList::reset
( (
std::initializer_list<const char* const> input std::initializer_list<const char* const> input

View File

@ -25,8 +25,6 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "SubStrings.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class ListType> template<class ListType>
@ -45,6 +43,7 @@ int Foam::CStringList::resetContent(const ListType& input)
// Count overall required string length, including each trailing nul char // Count overall required string length, including each trailing nul char
for (const auto& s : input) for (const auto& s : input)
{ {
// NB: use length() instead of size() to support std::sub_match
nbytes_ += s.length() + 1; nbytes_ += s.length() + 1;
} }
--nbytes_; // Do not include final nul char in overall count --nbytes_; // Do not include final nul char in overall count

View File

@ -86,16 +86,7 @@ inline Foam::CStringList::CStringList(const UList<StringType>& input)
: :
CStringList() CStringList()
{ {
reset(input); resetContent(input);
}
template<class StringType>
inline Foam::CStringList::CStringList(const SubStrings<StringType>& input)
:
CStringList()
{
reset(input);
} }
@ -127,56 +118,10 @@ inline void Foam::CStringList::clear()
} }
inline bool Foam::CStringList::empty() const noexcept
{
return !argc_;
}
inline int Foam::CStringList::size() const noexcept
{
return argc_;
}
inline char** Foam::CStringList::strings() const noexcept
{
return argv_;
}
inline char** Foam::CStringList::strings(int start) const inline char** Foam::CStringList::strings(int start) const
{ {
return &(argv_[start]); return &(argv_[start]);
} }
template<class StringType>
inline int Foam::CStringList::reset(const UList<StringType>& input)
{
return resetContent(input);
}
template<class StringType>
inline int Foam::CStringList::reset(const SubStrings<StringType>& input)
{
return resetContent(input);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline const char* Foam::CStringList::get(int i) const
{
return argv_[i];
}
inline const char* Foam::CStringList::operator[](int i) const
{
return argv_[i];
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -35,7 +35,7 @@ Description
#ifndef Foam_SubStrings_H #ifndef Foam_SubStrings_H
#define Foam_SubStrings_H #define Foam_SubStrings_H
#include <regex> // For std::sub_match #include <regex> // For std::ssub_match
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
@ -49,22 +49,32 @@ namespace Foam
Class SubStrings Declaration Class SubStrings Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class StringType>
class SubStrings class SubStrings
: :
public std::vector<std::sub_match<typename StringType::const_iterator>> public std::vector<std::ssub_match>
{ {
public: public:
// Types // Static Functions
//- The element type #if __cplusplus >= 201703L
using value_type = //- Return match as a string_view
typename std::sub_match<typename StringType::const_iterator>; static std::string_view view(const std::ssub_match& m)
{
if (!m.matched) return std::string_view();
//- The const_iterator for the underlying string type #if __cplusplus >= 202002L
using string_iterator = return std::string_view(m.first, m.second);
typename StringType::const_iterator; #else
// No string_view construct from iterator pairs before c++20
return std::string_view
(
std::pointer_traits<const char*>::pointer_to(*(m.first)),
(m.second - m.first)
);
#endif
}
#endif /* __cplusplus >= 201703L */
// Member Functions // Member Functions
@ -89,8 +99,8 @@ public:
return (*this)[pos].length(); return (*this)[pos].length();
} }
//- Retrieve element at pos, converted to a string type. //- Retrieve element at pos, as a string
StringType str(size_t pos) const std::string str(size_t pos) const
{ {
return (*this)[pos].str(); return (*this)[pos].str();
} }
@ -99,40 +109,23 @@ public:
//- Return element at pos as a string_view //- Return element at pos as a string_view
std::string_view view(size_t pos) const std::string_view view(size_t pos) const
{ {
#if __cplusplus >= 202002L return view((*this)[pos]);
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 */ #endif /* __cplusplus >= 201703L */
//- Append sub-string defined by begin/end iterators //- Append sub-string defined by begin/end iterators
void append void append
( (
const typename StringType::const_iterator& b, std::string::const_iterator b,
const typename StringType::const_iterator& e std::string::const_iterator e
) )
{ {
value_type range; auto& range = this->emplace_back();
range.first = b; range.first = b;
range.second = e; range.second = e;
range.matched = true; range.matched = true;
this->push_back(range);
} }
//- Reduce size by 1 or more elements. Can be called on an empty list. //- Reduce size by 1 or more elements. Can be called on an empty list.
void pop_back(size_t n = 1) void pop_back(size_t n = 1)
{ {

View File

@ -32,8 +32,8 @@ Description
situations than using the normal list find/found methods. situations than using the normal list find/found methods.
SourceFiles SourceFiles
hashedWordList.cxx
hashedWordListI.H hashedWordListI.H
hashedWordList.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/

View File

@ -37,7 +37,7 @@ Description
Various utility functions to work on lists of strings. Various utility functions to work on lists of strings.
SourceFiles SourceFiles
stringListOpsTemplates.C stringListOps.txx
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -486,7 +486,7 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "stringListOpsTemplates.C" #include "stringListOps.txx"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation Copyright (C) 2011-2012 OpenFOAM Foundation
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.
@ -31,8 +31,10 @@ Description
Collection of static functions for various string-related operations Collection of static functions for various string-related operations
SourceFiles SourceFiles
stringOps.C stringOps.cxx
stringOpsTemplates.C stringOps.txx
stringOpsSplit.cxx
stringOpsSubstr.cxx
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -40,9 +42,9 @@ SourceFiles
#define Foam_stringOps_H #define Foam_stringOps_H
#include "scalar.H" #include "scalar.H"
#include "SubStrings.H"
#include "dictionary.H" #include "dictionary.H"
#include "HashTable.H" #include "HashTable.H"
#include "SubStrings.H"
#include "stringOpsSort.H" #include "stringOpsSort.H"
#include "stringOpsEvaluate.H" #include "stringOpsEvaluate.H"
#include "word.H" #include "word.H"
@ -369,11 +371,10 @@ namespace stringOps
//- Split string into sub-strings at the delimiter character. //- Split string into sub-strings at the delimiter character.
// Empty sub-strings are normally suppressed. // Empty sub-strings are normally suppressed.
// Behaviour is ill-defined if delim is a NUL character. // Behaviour is ill-defined if delim is a NUL character.
template<class StringType> Foam::SubStrings split
Foam::SubStrings<StringType> split
( (
//! The string to split //! The string to split
const StringType& str, const std::string& str,
//! The delimiter for splitting. Ill-defined if NUL character //! The delimiter for splitting. Ill-defined if NUL character
const char delim, const char delim,
//! Offset within string to start splitting //! Offset within string to start splitting
@ -384,11 +385,10 @@ namespace stringOps
//- Split string into sub-strings using delimiter string. //- Split string into sub-strings using delimiter string.
// Empty sub-strings are normally suppressed. // Empty sub-strings are normally suppressed.
template<class StringType> Foam::SubStrings split
Foam::SubStrings<StringType> split
( (
//! The string to split //! The string to split
const StringType& str, const std::string& str,
//! The delimiters for splitting. Ill-defined if empty //! The delimiters for splitting. Ill-defined if empty
const std::string& delim, const std::string& delim,
//! Offset within string to start splitting //! Offset within string to start splitting
@ -400,11 +400,10 @@ namespace stringOps
//- Split string into sub-strings using any characters in delimiter. //- Split string into sub-strings using any characters in delimiter.
// Empty sub-strings are normally suppressed. // Empty sub-strings are normally suppressed.
// Behaviour is ill-defined if delim is an empty string. // Behaviour is ill-defined if delim is an empty string.
template<class StringType> Foam::SubStrings splitAny
Foam::SubStrings<StringType> splitAny
( (
//! The string to split //! The string to split
const StringType& str, const std::string& str,
//! The delimiters for splitting. Ill-defined if empty! //! The delimiters for splitting. Ill-defined if empty!
const std::string& delim, const std::string& delim,
//! Offset within string to start splitting //! Offset within string to start splitting
@ -413,11 +412,10 @@ namespace stringOps
//- Split string into sub-strings using a fixed field width. //- Split string into sub-strings using a fixed field width.
// Behaviour is ill-defined if width is zero. // Behaviour is ill-defined if width is zero.
template<class StringType> Foam::SubStrings splitFixed
Foam::SubStrings<StringType> splitFixed
( (
//! The string to split //! The string to split
const StringType& str, const std::string& str,
//! Fixed field width for each sub-string //! Fixed field width for each sub-string
const std::string::size_type width, const std::string::size_type width,
//! Offset within string to start splitting //! Offset within string to start splitting
@ -426,11 +424,10 @@ namespace stringOps
//- Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC) //- Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC)
// Empty sub-strings are suppressed. // Empty sub-strings are suppressed.
template<class StringType> Foam::SubStrings splitSpace
Foam::SubStrings<StringType> splitSpace
( (
//! The string to split //! The string to split
const StringType& str, const std::string& str,
//! Offset within string to start splitting //! Offset within string to start splitting
std::string::size_type pos = 0 std::string::size_type pos = 0
); );
@ -460,7 +457,7 @@ namespace stringOps
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "stringOpsTemplates.C" #include "stringOps.txx"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -177,7 +177,7 @@ static void expandLeadingTilde(std::string& s)
} }
else else
{ {
s = home(user)/file; s = Foam::home(user)/file;
} }
} }
@ -1033,7 +1033,7 @@ Foam::stringOps::findTrim
++pos; ++pos;
} }
return std::pair<std::size_t, std::size_t>(pos, end); return {pos, end};
} }

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class StringType, class UnaryPredicate>
StringType Foam::stringOps::quotemeta
(
const StringType& str,
const UnaryPredicate& meta,
const char quote
)
{
if (str.empty() || !quote)
{
return str;
}
StringType result;
result.reserve(1.5*str.size()); // Moderately pessimistic
bool escaped = false;
for (const char c : str)
{
if (c == quote)
{
escaped = !escaped; // toggle state
}
else if (escaped)
{
escaped = false;
}
else if (meta(c))
{
result += quote;
}
result += c;
}
result.shrink_to_fit();
return result;
}
template<class StringType, class UnaryPredicate>
StringType Foam::stringOps::validate
(
const std::string& str,
const UnaryPredicate& accept,
const bool invert
)
{
StringType out;
out.resize(str.length());
std::string::size_type len = 0;
for (std::string::size_type i = 0; i < str.length(); ++i)
{
const char c = str[i];
if (accept(c) ? !invert : invert)
{
out[len++] += c;
}
}
out.erase(len);
return out;
}
// ************************************************************************* //

View File

@ -30,12 +30,12 @@ Description
Specialized string sorting. Specialized string sorting.
SourceFiles SourceFiles
stringOpsSort.C stringOpsSort.cxx
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef stringOpsSort_H #ifndef Foam_stringOpsSort_H
#define stringOpsSort_H #define Foam_stringOpsSort_H
#include "stringOps.H" #include "stringOps.H"

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd. Copyright (C) 2021-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -99,7 +99,7 @@ Foam::label Foam::stringOps::splitFunctionArgs
// The depth of the argument parsing // The depth of the argument parsing
int argLevel = 0; int argLevel = 0;
const auto strLen = str.length(); const auto strLen = str.size();
// Pass 1: parsing begin/end parse positions. // Pass 1: parsing begin/end parse positions.
@ -136,11 +136,11 @@ Foam::label Foam::stringOps::splitFunctionArgs
if (isNamed) if (isNamed)
{ {
named.push_back(argName); named.push_back(argName);
named.push_back(rangeType(beg, pos)); named.emplace_back(beg, pos);
} }
else else
{ {
unnamed.push_back(rangeType(beg, pos)); unnamed.emplace_back(beg, pos);
} }
isNamed = false; isNamed = false;
beg = pos + 1; beg = pos + 1;

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) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,84 +25,19 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "stringOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class StringType, class UnaryPredicate> Foam::SubStrings Foam::stringOps::split
StringType Foam::stringOps::quotemeta
(
const StringType& str,
const UnaryPredicate& meta,
const char quote
)
{
if (str.empty() || !quote)
{
return str;
}
StringType result;
result.reserve(1.5*str.size()); // Moderately pessimistic
bool escaped = false;
for (const char c : str)
{
if (c == quote)
{
escaped = !escaped; // toggle state
}
else if (escaped)
{
escaped = false;
}
else if (meta(c))
{
result += quote;
}
result += c;
}
result.shrink_to_fit();
return result;
}
template<class StringType, class UnaryPredicate>
StringType Foam::stringOps::validate
( (
const std::string& str, const std::string& str,
const UnaryPredicate& accept,
const bool invert
)
{
StringType out;
out.resize(str.length());
std::string::size_type len = 0;
for (std::string::size_type i = 0; i < str.length(); ++i)
{
const char c = str[i];
if (accept(c) ? !invert : invert)
{
out[len++] += c;
}
}
out.erase(len);
return out;
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::split
(
const StringType& str,
const char delim, const char delim,
std::string::size_type pos, std::string::size_type pos,
const bool keepEmpty const bool keepEmpty
) )
{ {
Foam::SubStrings<StringType> list; Foam::SubStrings list;
if if
( (
@ -135,16 +70,15 @@ Foam::SubStrings<StringType> Foam::stringOps::split
} }
template<class StringType> Foam::SubStrings Foam::stringOps::split
Foam::SubStrings<StringType> Foam::stringOps::split
( (
const StringType& str, const std::string& str,
const std::string& delim, const std::string& delim,
std::string::size_type pos, std::string::size_type pos,
const bool keepEmpty const bool keepEmpty
) )
{ {
Foam::SubStrings<StringType> list; Foam::SubStrings list;
if if
( (
@ -177,15 +111,14 @@ Foam::SubStrings<StringType> Foam::stringOps::split
} }
template<class StringType> Foam::SubStrings Foam::stringOps::splitAny
Foam::SubStrings<StringType> Foam::stringOps::splitAny
( (
const StringType& str, const std::string& str,
const std::string& delim, const std::string& delim,
std::string::size_type pos std::string::size_type pos
) )
{ {
Foam::SubStrings<StringType> list; Foam::SubStrings list;
if if
( (
@ -219,15 +152,14 @@ Foam::SubStrings<StringType> Foam::stringOps::splitAny
} }
template<class StringType> Foam::SubStrings Foam::stringOps::splitFixed
Foam::SubStrings<StringType> Foam::stringOps::splitFixed
( (
const StringType& str, const std::string& str,
const std::string::size_type width, const std::string::size_type width,
std::string::size_type pos std::string::size_type pos
) )
{ {
Foam::SubStrings<StringType> list; Foam::SubStrings list;
if if
( (
@ -263,10 +195,9 @@ Foam::SubStrings<StringType> Foam::stringOps::splitFixed
} }
template<class StringType> Foam::SubStrings Foam::stringOps::splitSpace
Foam::SubStrings<StringType> Foam::stringOps::splitSpace
( (
const StringType& str, const std::string& str,
std::string::size_type pos std::string::size_type pos
) )
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2022 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,7 +44,7 @@ namespace Foam
// l v1/vt1 v2/vt2 v3/vt3 ... // l v1/vt1 v2/vt2 v3/vt3 ...
static label readObjVertices static label readObjVertices
( (
const SubStrings<string>& tokens, const SubStrings& tokens,
DynamicList<label>& verts DynamicList<label>& verts
) )
{ {
@ -60,17 +60,20 @@ static label readObjVertices
continue; continue;
} }
const string vrtSpec(tok); std::string vrtSpec(tok.str());
const auto slash = vrtSpec.find('/');
const label vertId = if
( (
slash != string::npos const auto slash = vrtSpec.find('/');
? readLabel(vrtSpec.substr(0, slash)) slash != std::string::npos
: readLabel(vrtSpec) )
); {
vrtSpec.erase(slash);
}
verts.append(vertId - 1); label vertId = readLabel(vrtSpec);
verts.push_back(vertId - 1);
} }
return verts.size(); return verts.size();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015-2024 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -58,10 +58,9 @@ namespace Foam
// //
// thus call extractTimeset with minElements == 2 // thus call extractTimeset with minElements == 2
// //
template<class StringType>
static inline labelPair extractTimeset static inline labelPair extractTimeset
( (
const SubStrings<StringType>& split, const SubStrings& split,
const std::size_t minElements const std::size_t minElements
) )
{ {
@ -239,7 +238,7 @@ void Foam::ensightSurfaceReader::readCase(ISstream& is)
} }
string buffer; string buffer;
SubStrings<string> split; SubStrings split;
ParseSection parseState = ParseSection::UNKNOWN; ParseSection parseState = ParseSection::UNKNOWN;

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.
@ -191,8 +191,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
if (line.starts_with("$ANSA_NAME")) if (line.starts_with("$ANSA_NAME"))
{ {
// Keep empty elements when splitting // Keep empty elements when splitting
const auto args = const auto args = stringOps::split(line, ';', 0, true);
stringOps::split<std::string>(line, ';', 0, true);
if (args.size() > 4 && line.starts_with("$ANSA_NAME_COMMENT")) if (args.size() > 4 && line.starts_with("$ANSA_NAME_COMMENT"))
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -168,17 +168,20 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
continue; continue;
} }
const string vrtSpec(tok); std::string vrtSpec(tok.str());
const auto slash = vrtSpec.find('/');
const label vertId = if
( (
slash != string::npos const auto slash = vrtSpec.find('/');
? readLabel(vrtSpec.substr(0, slash)) slash != std::string::npos
: readLabel(vrtSpec) )
); {
vrtSpec.erase(slash);
}
dynVerts.append(vertId - 1); label vertId = readLabel(vrtSpec);
dynVerts.push_back(vertId - 1);
} }
const labelUList& f = dynVerts; const labelUList& f = dynVerts;

View File

@ -590,7 +590,7 @@ Foam::wordList Foam::basicThermo::splitThermoName
// Splits things like // Splits things like
// "hePsiThermo<pureMixture<const<hConst<perfectGas<specie>>,enthalpy>>>" // "hePsiThermo<pureMixture<const<hConst<perfectGas<specie>>,enthalpy>>>"
const auto parsed = stringOps::splitAny<std::string>(thermoName, " ,<>"); const auto parsed = stringOps::splitAny(thermoName, " ,<>");
const int nParsed(parsed.size()); const int nParsed(parsed.size());
wordList cmpts; wordList cmpts;