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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -119,6 +119,8 @@ static inline void* loadLibrary(const Foam::fileName& libName)
constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
#ifdef __APPLE__
using namespace Foam;
const char* normal = 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
// shadow parameter is available
const Foam::string ldPaths(shadow);
const auto paths = Foam::stringOps::split<Foam::string>(ldPaths, ':');
const std::string ldPaths(shadow);
const auto paths = Foam::stringOps::split(ldPaths, ':');
for (const auto& p : paths)
{

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -59,7 +59,7 @@ static List<expressions::exprString> expandExprStrings
for (const string& input : inputs)
{
// 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)
{

View File

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

View File

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

View File

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

View File

@ -25,8 +25,6 @@ License
\*---------------------------------------------------------------------------*/
#include "SubStrings.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class ListType>
@ -45,6 +43,7 @@ int Foam::CStringList::resetContent(const ListType& input)
// Count overall required string length, including each trailing nul char
for (const auto& s : input)
{
// NB: use length() instead of size() to support std::sub_match
nbytes_ += s.length() + 1;
}
--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()
{
reset(input);
}
template<class StringType>
inline Foam::CStringList::CStringList(const SubStrings<StringType>& input)
:
CStringList()
{
reset(input);
resetContent(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
{
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
#define Foam_SubStrings_H
#include <regex> // For std::sub_match
#include <regex> // For std::ssub_match
#include <memory>
#include <string>
#include <vector>
@ -49,22 +49,32 @@ namespace Foam
Class SubStrings Declaration
\*---------------------------------------------------------------------------*/
template<class StringType>
class SubStrings
:
public std::vector<std::sub_match<typename StringType::const_iterator>>
public std::vector<std::ssub_match>
{
public:
// Types
// Static Functions
//- The element type
using value_type =
typename std::sub_match<typename StringType::const_iterator>;
#if __cplusplus >= 201703L
//- Return match as a string_view
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
using string_iterator =
typename StringType::const_iterator;
#if __cplusplus >= 202002L
return std::string_view(m.first, m.second);
#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
@ -89,8 +99,8 @@ public:
return (*this)[pos].length();
}
//- Retrieve element at pos, converted to a string type.
StringType str(size_t pos) const
//- Retrieve element at pos, as a string
std::string str(size_t pos) const
{
return (*this)[pos].str();
}
@ -99,40 +109,23 @@ public:
//- 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
return view((*this)[pos]);
}
#endif /* __cplusplus >= 201703L */
//- Append sub-string defined by begin/end iterators
void append
(
const typename StringType::const_iterator& b,
const typename StringType::const_iterator& e
std::string::const_iterator b,
std::string::const_iterator e
)
{
value_type range;
auto& range = this->emplace_back();
range.first = b;
range.second = e;
range.matched = true;
this->push_back(range);
}
//- Reduce size by 1 or more elements. Can be called on an empty list.
void pop_back(size_t n = 1)
{

View File

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

View File

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

View File

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

View File

@ -177,7 +177,7 @@ static void expandLeadingTilde(std::string& s)
}
else
{
s = home(user)/file;
s = Foam::home(user)/file;
}
}
@ -1033,7 +1033,7 @@ Foam::stringOps::findTrim
++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.
SourceFiles
stringOpsSort.C
stringOpsSort.cxx
\*---------------------------------------------------------------------------*/
#ifndef stringOpsSort_H
#define stringOpsSort_H
#ifndef Foam_stringOpsSort_H
#define Foam_stringOpsSort_H
#include "stringOps.H"

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2024 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,84 +25,19 @@ License
\*---------------------------------------------------------------------------*/
#include "stringOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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
Foam::SubStrings Foam::stringOps::split
(
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,
std::string::size_type pos,
const bool keepEmpty
)
{
Foam::SubStrings<StringType> list;
Foam::SubStrings list;
if
(
@ -135,16 +70,15 @@ Foam::SubStrings<StringType> Foam::stringOps::split
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::split
Foam::SubStrings Foam::stringOps::split
(
const StringType& str,
const std::string& str,
const std::string& delim,
std::string::size_type pos,
const bool keepEmpty
)
{
Foam::SubStrings<StringType> list;
Foam::SubStrings list;
if
(
@ -177,15 +111,14 @@ Foam::SubStrings<StringType> Foam::stringOps::split
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::splitAny
Foam::SubStrings Foam::stringOps::splitAny
(
const StringType& str,
const std::string& str,
const std::string& delim,
std::string::size_type pos
)
{
Foam::SubStrings<StringType> list;
Foam::SubStrings list;
if
(
@ -219,15 +152,14 @@ Foam::SubStrings<StringType> Foam::stringOps::splitAny
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::splitFixed
Foam::SubStrings Foam::stringOps::splitFixed
(
const StringType& str,
const std::string& str,
const std::string::size_type width,
std::string::size_type pos
)
{
Foam::SubStrings<StringType> list;
Foam::SubStrings list;
if
(
@ -263,10 +195,9 @@ Foam::SubStrings<StringType> Foam::stringOps::splitFixed
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::splitSpace
Foam::SubStrings Foam::stringOps::splitSpace
(
const StringType& str,
const std::string& str,
std::string::size_type pos
)
{

View File

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

View File

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

View File

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

View File

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

View File

@ -590,7 +590,7 @@ Foam::wordList Foam::basicThermo::splitThermoName
// Splits things like
// "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());
wordList cmpts;