Commit b3ac6c3f authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: add Foam::SubStrings container and stringOps::split

- generic means of holding ranges of substring iterators
parent 1281543c
Test-stringSplit.C
EXE = $(FOAM_USER_APPBIN)/Test-stringSplit
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
Application
Test-stringSplit
Description
Test string splitting
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "fileName.H"
#include "stringOps.H"
using namespace Foam;
template<class String>
void printSplitting(const String& str, const char delimiter)
{
auto split = stringOps::split(str, delimiter);
Info<< "string {" << str.size() << " chars} = " << str << nl
<< split.size() << " elements {" << split.length() << " chars}"
<< nl;
unsigned i = 0;
for (const auto s : split)
{
Info<< "[" << i++ << "] {" << s.length() << " chars} = "
<< s.str() << nl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList args(argc, argv, false, true);
if (args.size() <= 1 && args.options().empty())
{
args.printUsage();
}
for (label argi=1; argi < args.size(); ++argi)
{
printSplitting(args[argi], '/');
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
Class
Foam::SubStrings
Description
Sub-ranges of a string with a structure similar to std::match_results,
but without the underlying regular expression matching.
\*---------------------------------------------------------------------------*/
#ifndef SubStrings_H
#define SubStrings_H
#include <string>
#include <regex>
#include <vector>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class SubStrings Declaration
\*---------------------------------------------------------------------------*/
template<class String>
class SubStrings
:
public std::vector<std::sub_match<typename String::const_iterator>>
{
public:
// Typedefs
//- The element type
using value_type =
typename std::sub_match<typename String::const_iterator>;
//- The const_iterator for the underlying string type
using string_iterator = typename String::const_iterator;
// Constructors
//- Construct null
SubStrings()
{}
// Member Functions
//- The total length of all sub-elements.
// Use size() for the number elements.
std::string::size_type length() const
{
std::string::size_type len = 0;
for (const auto& elem : *this)
{
len += elem.length();
}
return len;
}
//- Append sub-string defined by begin/end iterators
void append(string_iterator b, string_iterator e)
{
value_type range;
range.first = b;
range.second = e;
range.matched = true;
this->push_back(range);
}
//- Const reference to the first element,
// for consistency with other OpenFOAM containers
auto first() const -> decltype(this->front())
{
return this->front();
}
//- Const reference to the last element,
// for consistency with other OpenFOAM containers
auto last() const -> decltype(this->back())
{
return this->back();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
......@@ -30,12 +30,14 @@ Description
SourceFiles
stringOps.C
stringOpsTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef stringOps_H
#define stringOps_H
#include "string.H"
#include "SubStrings.H"
#include "word.H"
#include "dictionary.H"
#include "HashTable.H"
......@@ -302,14 +304,21 @@ namespace stringOps
Foam::word name(const std::string& fmt, const PrimitiveType& val);
} // End namespace stringOps
//- Split a string into sub-strings at the delimiter character.
// An empty sub-strings are suppressed.
template<class StringType>
Foam::SubStrings<StringType> split
(
const StringType& str,
const char delimiter
);
} // End namespace stringOps
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -65,4 +65,36 @@ Foam::word Foam::stringOps::name
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::split
(
const StringType& str,
const char delimiter
)
{
Foam::SubStrings<StringType> lst;
lst.reserve(20);
std::string::size_type beg = 0, end = 0;
while ((end = str.find(delimiter, beg)) != std::string::npos)
{
if (beg < end)
{
// (Non-empty) intermediate element
lst.append(str.cbegin() + beg, str.cbegin() + end);
}
beg = end + 1;
}
// (Non-empty) trailing element
if (beg < str.size())
{
lst.append(str.cbegin() + beg, str.cbegin() + str.size());
}
return lst;
}
// ************************************************************************* //
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment