From b3ac6c3fed34e3af4bb3e1498147f62bc801754a Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Thu, 20 Jul 2017 19:53:57 +0200 Subject: [PATCH] ENH: add Foam::SubStrings container and stringOps::split - generic means of holding ranges of substring iterators --- applications/test/stringSplit/Make/files | 3 + applications/test/stringSplit/Make/options | 0 .../test/stringSplit/Test-stringSplit.C | 81 +++++++++++ .../primitives/strings/lists/SubStrings.H | 127 ++++++++++++++++++ .../primitives/strings/stringOps/stringOps.H | 13 +- .../strings/stringOps/stringOpsTemplates.C | 34 ++++- 6 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 applications/test/stringSplit/Make/files create mode 100644 applications/test/stringSplit/Make/options create mode 100644 applications/test/stringSplit/Test-stringSplit.C create mode 100644 src/OpenFOAM/primitives/strings/lists/SubStrings.H diff --git a/applications/test/stringSplit/Make/files b/applications/test/stringSplit/Make/files new file mode 100644 index 0000000000..06bdafe1b2 --- /dev/null +++ b/applications/test/stringSplit/Make/files @@ -0,0 +1,3 @@ +Test-stringSplit.C + +EXE = $(FOAM_USER_APPBIN)/Test-stringSplit diff --git a/applications/test/stringSplit/Make/options b/applications/test/stringSplit/Make/options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/applications/test/stringSplit/Test-stringSplit.C b/applications/test/stringSplit/Test-stringSplit.C new file mode 100644 index 0000000000..9b1208c252 --- /dev/null +++ b/applications/test/stringSplit/Test-stringSplit.C @@ -0,0 +1,81 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/lists/SubStrings.H b/src/OpenFOAM/primitives/strings/lists/SubStrings.H new file mode 100644 index 0000000000..3e37fd7edd --- /dev/null +++ b/src/OpenFOAM/primitives/strings/lists/SubStrings.H @@ -0,0 +1,127 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H index 66e87623e5..0d7d459f59 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H @@ -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 diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOpsTemplates.C b/src/OpenFOAM/primitives/strings/stringOps/stringOpsTemplates.C index a8f7030300..1b0aa62e9f 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOpsTemplates.C +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOpsTemplates.C @@ -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; +} + + // ************************************************************************* // -- GitLab