ENH: add stringOps::inplaceRemoveSpace()

Style changes:
  - use std algorithm for some stringOps internals
  - pass SubStrings iterators by const reference

ENH: special nullptr handling for ISstream getLine
  - pass through to istream::ignore to support read and discard
This commit is contained in:
Mark Olesen
2020-02-19 14:16:45 +01:00
parent 6b3b6bb99f
commit 5f93f20652
12 changed files with 224 additions and 117 deletions

View File

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

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
Application
Test-IFstream
Description
Tests on low-level reading
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Fstream.H"
#include "etcFiles.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
#include "setRootCase.H"
// Test with etc/controlDict (mandatory, from distribution)
{
const fileName inputFile
(
findEtcFile("controlDict", true, 0007)
);
Info<< nl << "Test getLine" << nl << inputFile << nl;
IFstream is(inputFile);
string buf;
// Test that buffer resizing works as expected
Info<< "buf: " << buf.size() << '/' << buf.capacity() << nl;
bool skipDoc = true;
while (is.good())
{
if (skipDoc || is.lineNumber() % 2)
{
is.getLine(buf);
Info<< is.lineNumber() << ": "
<< buf.size() << '/' << buf.capacity() << ' '
<< buf << nl;
if (buf.starts_with("Documentation"))
{
skipDoc = false;
Info<< "Found Documentation: skip until closing '}'"
<< " line number will now be incorrect"
<< nl;
auto n = is.getLine(nullptr, '}');
Info<< is.lineNumber() << ": [" << label(n) << "]" << nl;
}
}
else
{
auto n = is.getLine(nullptr);
Info<< is.lineNumber() << ": [" << label(n) << "]" << nl;
}
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -41,6 +41,7 @@ SourceFiles
#include "Istream.H" #include "Istream.H"
#include "fileName.H" #include "fileName.H"
#include <limits>
#include <iostream> #include <iostream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -148,9 +149,13 @@ public:
// end of file is read. // end of file is read.
inline int peek(); inline int peek();
//- Raw, low-level getline into a string function. //- Raw, low-level getline (until delimiter) into a string.
inline ISstream& getLine(std::string& str, char delim = '\n'); inline ISstream& getLine(std::string& str, char delim = '\n');
//- Low-level discard until delimiter
// \return the number of characters extracted
inline std::streamsize getLine(std::nullptr_t, char delim = '\n');
//- Raw, low-level putback character function. //- Raw, low-level putback character function.
inline ISstream& putback(const char c); inline ISstream& putback(const char c);

View File

@ -87,6 +87,22 @@ inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
} }
inline std::streamsize Foam::ISstream::getLine(std::nullptr_t, char delim)
{
is_.ignore(std::numeric_limits<std::streamsize>::max(), delim);
setState(is_.rdstate());
std::streamsize count = is_.gcount();
if (count && delim == '\n')
{
++lineNumber_;
}
return count;
}
inline Foam::ISstream& Foam::ISstream::putback(const char c) inline Foam::ISstream& Foam::ISstream::putback(const char c)
{ {
if (c == '\n') if (c == '\n')

View File

@ -134,12 +134,12 @@ void Foam::csvTableReader<Type>::operator()
const label maxEntry = const label maxEntry =
max(refColumn_, componentColumns_[findMax(componentColumns_)]); max(refColumn_, componentColumns_[findMax(componentColumns_)]);
string line;
label lineNo = 0; label lineNo = 0;
// Skip header // Skip header
if (headerLine_) if (headerLine_)
{ {
string line;
is.getLine(line); is.getLine(line);
++lineNo; ++lineNo;
} }
@ -149,7 +149,6 @@ void Foam::csvTableReader<Type>::operator()
while (is.good()) while (is.good())
{ {
string line;
is.getLine(line); is.getLine(line);
++lineNo; ++lineNo;

View File

@ -118,12 +118,12 @@ void Foam::Function1Types::CSV<Type>::read()
const label maxEntry = const label maxEntry =
max(refColumn_, componentColumns_[findMax(componentColumns_)]); max(refColumn_, componentColumns_[findMax(componentColumns_)]);
string line;
label lineNo = 0; label lineNo = 0;
// Skip header // Skip header
for (label i = 0; i < nHeaderLine_; ++i) for (label i = 0; i < nHeaderLine_; ++i)
{ {
string line;
is.getLine(line); is.getLine(line);
++lineNo; ++lineNo;
} }
@ -133,7 +133,6 @@ void Foam::Function1Types::CSV<Type>::read()
while (is.good()) while (is.good())
{ {
string line;
is.getLine(line); is.getLine(line);
++lineNo; ++lineNo;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -35,8 +35,8 @@ Description
#ifndef SubStrings_H #ifndef SubStrings_H
#define SubStrings_H #define SubStrings_H
#include <string>
#include <regex> #include <regex>
#include <string>
#include <vector> #include <vector>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -67,13 +67,13 @@ public:
// Constructors // Constructors
//- Construct null //- Default construct
SubStrings() = default; SubStrings() = default;
// Member Functions // Member Functions
//- The total length of all sub-elements. //- The total string length of all sub-elements.
// Use size() for the number elements. // Use size() for the number elements.
std::string::size_type length() const std::string::size_type length() const
{ {
@ -89,7 +89,11 @@ public:
//- Append sub-string defined by begin/end iterators //- Append sub-string defined by begin/end iterators
void append(string_iterator b, string_iterator e) void append
(
const typename String::const_iterator& b,
const typename String::const_iterator& e
)
{ {
value_type range; value_type range;
range.first = b; range.first = b;
@ -101,7 +105,7 @@ public:
//- Const reference to the first element, //- Const reference to the first element,
// for consistency with other OpenFOAM containers //- for consistency with other OpenFOAM containers
auto first() const -> decltype(this->front()) auto first() const -> decltype(this->front())
{ {
return this->front(); return this->front();
@ -109,7 +113,7 @@ public:
//- Const reference to the last element, //- Const reference to the last element,
// for consistency with other OpenFOAM containers //- for consistency with other OpenFOAM containers
auto last() const -> decltype(this->back()) auto last() const -> decltype(this->back())
{ {
return this->back(); return this->back();
@ -121,9 +125,9 @@ public:
{ {
return (*this)[pos].str(); return (*this)[pos].str();
} }
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

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-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -190,7 +190,7 @@ bool Foam::string::removeRepeated(const char character)
} }
} }
resize(nChar); erase(nChar);
} }
return changed; return changed;
@ -219,7 +219,7 @@ bool Foam::string::removeEnd(const std::string& text)
if (txtLen && strLen >= txtLen && !compare(strLen - txtLen, npos, text)) if (txtLen && strLen >= txtLen && !compare(strLen - txtLen, npos, text))
{ {
resize(strLen - txtLen); erase(strLen - txtLen);
return true; return true;
} }
@ -244,7 +244,7 @@ bool Foam::string::removeEnd(const char c)
const auto n = length(); const auto n = length();
if (n > 1 && back() == c) if (n > 1 && back() == c)
{ {
resize(n-1); erase(n-1);
return true; return true;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,10 +29,11 @@ License
#include "stringOps.H" #include "stringOps.H"
#include "typeInfo.H" #include "typeInfo.H"
#include "etcFiles.H" #include "etcFiles.H"
#include "Pstream.H" #include "UPstream.H"
#include "StringStream.H" #include "StringStream.H"
#include "OSstream.H" #include "OSstream.H"
#include "OSspecific.H" #include "OSspecific.H"
#include <algorithm>
#include <cctype> #include <cctype>
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -162,7 +163,7 @@ static void expandLeadingTilde(std::string& s)
// Single warning (on master) with guard to avoid Pstream::master() // Single warning (on master) with guard to avoid Pstream::master()
// when Pstream has not yet been initialized // when Pstream has not yet been initialized
if (Pstream::parRun() ? Pstream::master() : true) if (UPstream::parRun() ? UPstream::master() : true)
{ {
std::cerr std::cerr
<< nl << nl
@ -696,55 +697,35 @@ static void expandString
std::string::size_type Foam::stringOps::count std::string::size_type Foam::stringOps::count
( (
const std::string& str, const std::string& s,
const char c const char c
) )
{ {
std::string::size_type n = 0; return std::count(s.cbegin(), s.cend(), c);
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
if (*iter == c)
{
++n;
}
}
return n;
} }
std::string::size_type Foam::stringOps::count(const char* str, const char c) std::string::size_type Foam::stringOps::count(const char* s, const char c)
{ {
if (!str) return
{ (
return 0; s == nullptr
} ? 0
: std::count(s, (s + std::char_traits<char>::length(s)), c)
std::string::size_type n = 0; );
for (const char *iter = str; *iter; ++iter)
{
if (*iter == c)
{
++n;
}
}
return n;
} }
Foam::string Foam::stringOps::expand Foam::string Foam::stringOps::expand
( (
const std::string& str, const std::string& s,
const HashTable<string, word, string::hash>& mapping, const HashTable<string, word, string::hash>& mapping,
const char sigil const char sigil
) )
{ {
string s(str); string out(s);
inplaceExpand(s, mapping); inplaceExpand(out, mapping);
return s; return out;
} }
@ -862,14 +843,14 @@ void Foam::stringOps::inplaceExpand
Foam::string Foam::stringOps::expand Foam::string Foam::stringOps::expand
( (
const std::string& str, const std::string& s,
const dictionary& dict, const dictionary& dict,
const char sigil const char sigil
) )
{ {
string s(str); string out(s);
inplaceExpand(s, dict, sigil); inplaceExpand(out, dict, sigil);
return s; return out;
} }
@ -902,13 +883,13 @@ void Foam::stringOps::inplaceExpand
Foam::string Foam::stringOps::expand Foam::string Foam::stringOps::expand
( (
const std::string& str, const std::string& s,
const bool allowEmpty const bool allowEmpty
) )
{ {
string s(str); string out(s);
inplaceExpand(s, allowEmpty); inplaceExpand(out, allowEmpty);
return s; return out;
} }
@ -1064,24 +1045,24 @@ Foam::stringOps::findTrim
} }
Foam::string Foam::stringOps::trim(const std::string& str) Foam::string Foam::stringOps::trim(const std::string& s)
{ {
std::string::size_type pos = 0; std::string::size_type pos = 0;
std::string::size_type end = str.length(); std::string::size_type end = s.length();
// Right // Right
while (pos < end && std::isspace(str[end-1])) while (pos < end && std::isspace(s[end-1]))
{ {
--end; --end;
} }
// Left // Left
while (pos < end && std::isspace(str[pos])) while (pos < end && std::isspace(s[pos]))
{ {
++pos; ++pos;
} }
return str.substr(pos, end-pos); return s.substr(pos, end-pos);
} }
@ -1092,11 +1073,17 @@ void Foam::stringOps::inplaceTrim(std::string& s)
} }
Foam::string Foam::stringOps::removeComments(const std::string& str) void Foam::stringOps::inplaceRemoveSpace(std::string& s)
{ {
string s(str); s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
inplaceRemoveComments(s); }
return s;
Foam::string Foam::stringOps::removeComments(const std::string& s)
{
string out(s);
inplaceRemoveComments(out);
return out;
} }
@ -1196,43 +1183,35 @@ void Foam::stringOps::inplaceRemoveComments(std::string& s)
} }
Foam::string Foam::stringOps::lower(const std::string& str) Foam::string Foam::stringOps::lower(const std::string& s)
{ {
string s(str); string out;
inplaceLower(s); out.resize(s.length());
return s;
std::transform(s.begin(), s.end(), out.begin(), ::tolower);
return out;
} }
void Foam::stringOps::inplaceLower(std::string& s) void Foam::stringOps::inplaceLower(std::string& s)
{ {
for (auto iter = s.begin(); iter != s.end(); ++iter) std::transform(s.begin(), s.end(), s.begin(), ::tolower);
{
*iter = static_cast<std::string::value_type>
(
std::tolower(static_cast<unsigned char>(*iter))
);
}
} }
Foam::string Foam::stringOps::upper(const std::string& str) Foam::string Foam::stringOps::upper(const std::string& s)
{ {
string s(str); string out;
inplaceUpper(s); out.resize(s.length());
return s;
std::transform(s.begin(), s.end(), out.begin(), ::toupper);
return out;
} }
void Foam::stringOps::inplaceUpper(std::string& s) void Foam::stringOps::inplaceUpper(std::string& s)
{ {
for (auto iter = s.begin(); iter != s.end(); ++iter) std::transform(s.begin(), s.end(), s.begin(), ::toupper);
{
*iter = static_cast<std::string::value_type>
(
std::toupper(static_cast<unsigned char>(*iter))
);
}
} }

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-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -55,7 +55,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class OSstream; class OSstream;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -65,11 +65,11 @@ class OSstream;
namespace stringOps namespace stringOps
{ {
//- Count the number of occurrences of the specified character //- Count the number of occurrences of the specified character
std::string::size_type count(const std::string& str, const char c); std::string::size_type count(const std::string& s, const char c);
//- Count the number of occurrences of the specified character //- Count the number of occurrences of the specified character
// Correctly handles nullptr. // Correctly handles nullptr.
std::string::size_type count(const char* str, const char c); std::string::size_type count(const char* s, const char c);
//- Return true if text matches one of the regular expressions. //- Return true if text matches one of the regular expressions.
inline bool match(const UList<wordRe>& patterns, const std::string& text) inline bool match(const UList<wordRe>& patterns, const std::string& text)
@ -83,7 +83,7 @@ namespace stringOps
// \sa stringOps::inplaceExpand() for details // \sa stringOps::inplaceExpand() for details
string expand string expand
( (
const std::string& str, const std::string& s,
const HashTable<string, word, string::hash>& mapping, const HashTable<string, word, string::hash>& mapping,
const char sigil = '$' const char sigil = '$'
); );
@ -213,7 +213,7 @@ namespace stringOps
// \sa stringOps::inplaceExpand(std::string&, const dictionary&, char) // \sa stringOps::inplaceExpand(std::string&, const dictionary&, char)
string expand string expand
( (
const std::string& str, const std::string& s,
const dictionary& dict, const dictionary& dict,
const char sigil = '$' const char sigil = '$'
); );
@ -246,11 +246,7 @@ namespace stringOps
// //
// \sa // \sa
// stringOps::inplaceExpand(std::string&, bool); // stringOps::inplaceExpand(std::string&, bool);
string expand string expand(const std::string& s, const bool allowEmpty = false);
(
const std::string& str,
const bool allowEmpty = false
);
//- Expand initial tags, tildes, and all occurrences of environment //- Expand initial tags, tildes, and all occurrences of environment
@ -268,11 +264,7 @@ namespace stringOps
// - allow empty = Given by parameter (default: False) // - allow empty = Given by parameter (default: False)
// - subDict = Not applicable // - subDict = Not applicable
// . // .
void inplaceExpand void inplaceExpand(std::string& s, const bool allowEmpty = false);
(
std::string& s,
const bool allowEmpty = false
);
//- Replace environment variable contents with its name. //- Replace environment variable contents with its name.
@ -305,27 +297,30 @@ namespace stringOps
void inplaceTrimRight(std::string& s); void inplaceTrimRight(std::string& s);
//- Return string trimmed of leading and trailing whitespace //- Return string trimmed of leading and trailing whitespace
string trim(const std::string& str); string trim(const std::string& s);
//- Trim leading and trailing whitespace inplace //- Trim leading and trailing whitespace inplace
void inplaceTrim(std::string& s); void inplaceTrim(std::string& s);
//- Eliminate whitespace inplace
void inplaceRemoveSpace(std::string& s);
//- Return string with C/C++ comments removed //- Return string with C/C++ comments removed
string removeComments(const std::string& str); string removeComments(const std::string& s);
//- Remove C/C++ comments inplace //- Remove C/C++ comments inplace
void inplaceRemoveComments(std::string& s); void inplaceRemoveComments(std::string& s);
//- Return string transformed with std::tolower on each character //- Return string copy transformed with std::tolower on each character
string lower(const std::string& str); string lower(const std::string& s);
//- Inplace transform string with std::tolower on each character //- Inplace transform string with std::tolower on each character
void inplaceLower(std::string& s); void inplaceLower(std::string& s);
//- Return string transformed with std::toupper on each character //- Return string copy transformed with std::toupper on each character
string upper(const std::string& str); string upper(const std::string& s);
//- Inplace transform string with std::toupper on each character //- Inplace transform string with std::toupper on each character
void inplaceUpper(std::string& s); void inplaceUpper(std::string& s);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -68,7 +68,7 @@ Foam::word Foam::word::validate(const std::string& s, const bool prefix)
} }
} }
out.resize(len); out.erase(len);
return out; return out;
} }
@ -102,7 +102,7 @@ Foam::word Foam::word::validate
} }
} }
out.resize(len); out.erase(len);
return out; return out;
} }