ENH: stringOps::findTrim helper

- finds beg/end indices of string trimmed of leading/trailing whitespace
This commit is contained in:
Mark Olesen
2019-12-13 12:10:53 +01:00
parent b61d4ab488
commit 17d9969ae5
4 changed files with 133 additions and 56 deletions

View File

@ -2,8 +2,10 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -93,6 +95,30 @@ void testNumericEvaluation(const std::string& s)
} }
// Test findTrim - uses '<' and '>' as pseudo-placeholders
void testFindTrim(const std::string& s)
{
auto pos = s.find('<');
auto len = s.find('>');
// Conform with expected value for substr
if (pos == std::string::npos) pos = 0; else ++pos;
if (len != std::string::npos) len = (len - pos);
const auto pts = stringOps::findTrim(s, pos, len);
Info<< "input" << nl
<< "========" << nl
<< s << nl
<< "pos=" << pos << " len=" << int(len) << nl
<< s.substr(pos, len) << nl
<< "trim=" << pts.first << " to " << pts.second << nl
<< s.substr(pts.first, pts.second-pts.first) << nl
<< "========" << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -150,6 +176,28 @@ int main(int argc, char *argv[])
} }
// Test findTrim - uses '<' and '>' as pseudo-placeholders
{
Info<< nl << "Test findTrim" << nl;
for
(
const auto& cstr
:
{
"", // Empty
" \n\t ", // whitespace only
" Leading and trailing ",
" Alt end and trai>ling ",
" Alt start< space ",
}
)
{
testFindTrim(cstr);
}
}
Info<< "\nEnd\n" << endl; Info<< "\nEnd\n" << endl;
return 0; return 0;
} }

View File

@ -947,15 +947,17 @@ Foam::string Foam::stringOps::trimLeft(const std::string& s)
{ {
if (!s.empty()) if (!s.empty())
{ {
std::string::size_type beg = 0; std::string::size_type pos = 0;
while (beg < s.size() && std::isspace(s[beg])) const auto end = s.length();
while (pos < end && std::isspace(s[pos]))
{ {
++beg; ++pos;
} }
if (beg) if (pos)
{ {
return s.substr(beg); return s.substr(pos);
} }
} }
@ -967,15 +969,17 @@ void Foam::stringOps::inplaceTrimLeft(std::string& s)
{ {
if (!s.empty()) if (!s.empty())
{ {
std::string::size_type beg = 0; std::string::size_type pos = 0;
while (beg < s.size() && std::isspace(s[beg])) const auto end = s.length();
while (pos < end && std::isspace(s[pos]))
{ {
++beg; ++pos;
} }
if (beg) if (pos)
{ {
s.erase(0, beg); s.erase(0, pos);
} }
} }
} }
@ -985,15 +989,15 @@ Foam::string Foam::stringOps::trimRight(const std::string& s)
{ {
if (!s.empty()) if (!s.empty())
{ {
auto n = s.size(); auto end = s.length();
while (n && std::isspace(s[n-1])) while (end && std::isspace(s[end-1]))
{ {
--n; --end;
} }
if (n < s.size()) if (end < s.length())
{ {
return s.substr(0, n); return s.substr(0, end);
} }
} }
@ -1005,35 +1009,74 @@ void Foam::stringOps::inplaceTrimRight(std::string& s)
{ {
if (!s.empty()) if (!s.empty())
{ {
auto n = s.size(); auto end = s.length();
while (n && std::isspace(s[n-1])) while (end && std::isspace(s[end-1]))
{ {
--n; --end;
} }
s.resize(n); s.erase(end);
} }
} }
std::pair<std::size_t, std::size_t>
Foam::stringOps::findTrim
(
const std::string& s,
std::size_t pos,
std::size_t len
)
{
size_t end = s.length();
if (pos >= end)
{
pos = end;
}
else if (len != std::string::npos)
{
len += pos;
if (len < end)
{
end = len;
}
}
// Right = last
while (pos < end && std::isspace(s[end-1]))
{
--end;
}
// Left = first
while (pos < end && std::isspace(s[pos]))
{
++pos;
}
return std::pair<std::size_t, std::size_t>(pos, end);
}
Foam::string Foam::stringOps::trim(const std::string& str) Foam::string Foam::stringOps::trim(const std::string& str)
{ {
std::string::size_type beg = 0; std::string::size_type pos = 0;
std::string::size_type end = str.size(); std::string::size_type end = str.length();
// Right // Right
while (beg < end && std::isspace(str[end-1])) while (pos < end && std::isspace(str[end-1]))
{ {
--end; --end;
} }
// Left // Left
while (beg < end && std::isspace(str[beg])) while (pos < end && std::isspace(str[pos]))
{ {
++beg; ++pos;
} }
return str.substr(beg, end-beg); return str.substr(pos, end-pos);
} }

View File

@ -36,6 +36,7 @@ SourceFiles
stringOpsTemplates.C stringOpsTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef stringOps_H #ifndef stringOps_H
#define stringOps_H #define stringOps_H
@ -48,6 +49,7 @@ SourceFiles
#include "stringOpsSort.H" #include "stringOpsSort.H"
#include "stringOpsEvaluate.H" #include "stringOpsEvaluate.H"
#include "wordRes.H" #include "wordRes.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -257,6 +259,16 @@ namespace stringOps
bool inplaceReplaceVar(std::string& s, const word& varName); bool inplaceReplaceVar(std::string& s, const word& varName);
//- Find (first, last) non-space locations in string or sub-string.
// This may change to std::string_view in the future.
std::pair<size_t, size_t>
findTrim
(
const std::string& s,
size_t pos = 0,
size_t len = std::string::npos
);
//- Return string trimmed of leading whitespace //- Return string trimmed of leading whitespace
string trimLeft(const std::string& s); string trimLeft(const std::string& s);

View File

@ -42,42 +42,16 @@ Foam::string Foam::stringOps::evaluate
{ {
/// InfoErr<< "Evaluate " << str.substr(pos, len) << nl; /// InfoErr<< "Evaluate " << str.substr(pos, len) << nl;
size_t end = str.length(); const auto trimPoints = stringOps::findTrim(str, pos, len);
if (pos > end)
{
pos = end;
}
else if (len != std::string::npos)
{
len += pos;
if (len < end) pos = trimPoints.first;
{ len = (trimPoints.second - trimPoints.first);
end = len;
}
}
// Adjust like inplaceTrim if (!len)
// Right
while (pos < end && std::isspace(str[end-1]))
{
--end;
}
// Left
while (pos < end && std::isspace(str[pos]))
{
++pos;
}
if ((pos >= end) || std::isspace(str[pos]))
{ {
return ""; return "";
} }
len = (end - pos);
/// InfoErr<< "Evaluate " << str.substr(pos, len) << nl; /// InfoErr<< "Evaluate " << str.substr(pos, len) << nl;
expressions::exprResult result; expressions::exprResult result;