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

ENH: add move/swap semantics to string types and regExp

- move append() single element to List and DynamicList

ENH: add stringOps::count to avoid unnecessary string conversions
parent cae8a894
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
Info<< "Test expressions:" << rawList << endl;
IOobject::writeDivider(Info) << endl;
List<string> groups;
List<std::string> groups;
// Report matches:
forAll(rawList, elemI)
......@@ -74,7 +74,23 @@ int main(int argc, char *argv[])
Info<< "false";
}
}
Info<< endl;
if (false)
{
regExp re2(std::move(re));
Info<<"move construct: " << re.exists() << "/" << re2.exists()
<< endl;
re = std::move(re2);
Info<<"move assign: " << re.exists() << "/" << re2.exists()
<< endl;
re.swap(re2);
Info<<"swap: " << re.exists() << "/" << re2.exists()
<< endl;
}
}
Info<< nl << "test regExp(const char*) ..." << endl;
......
......@@ -69,6 +69,65 @@ int main(int argc, char *argv[])
Info<<"trimRight: " << stringOps::trimRight(test) << endl;
Info<<"trim: " << stringOps::trim(test) << endl;
if (false)
{
Info<<"test move construct - string size:" << test.size() << nl;
string test2(std::move(test));
Info<<"input size:" << test.size() << nl;
Info<<"moved size:" << test2.size() << nl;
Info<<"test move assign - string sizes:"
<< test.size() << "/" << test2.size() << nl;
test = std::move(test2);
Info<<"input size:" << test.size() << nl;
Info<<"moved size:" << test2.size() << nl;
}
if (false)
{
std::string str("some text");
Info<<"test move construct to string:" << str.size() << nl;
Foam::string test2(std::move(str));
Info<<"input/moved sizes:" << str.size() << "/" << test2.size() << nl;
str = std::move(test2);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
}
if (false)
{
Foam::string str("thisIsAWord");
Info<<"test move construct to word:" << str.size() << nl;
word test2(std::move(str));
Info<<"input/moved sizes:" << str.size() << "/" << test2.size() << nl;
str = std::move(test2);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
// move back
test2.swap(str);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
string str2(std::move(test2));
Info<<"input/moved sizes:" << test2.size() << "/" << str2.size() << nl;
}
{
fileName test1("libFooBar.so");
......
......@@ -56,6 +56,56 @@ int main(int argc, char *argv[])
{"file[a-b]", wordRe::REGEX},
};
if (true)
{
Info<<"keyType: " << keyre << endl;
keyType key2(std::move(keyre));
Info<<"move construct: <" << keyre << "> <" << key2 << ">" << endl;
keyre = std::move(key2);
Info<<"move assign: <" << keyre << "> <" << key2 << ">" << endl;
keyType key3;
keyre.swap(key3);
Info<<"swap: <" << keyre << "> <" << key3 << ">" << endl;
keyre = std::move(key3);
Info<<"move assign: <" << keyre << "> <" << key3 << ">" << endl;
return 0;
}
if (false)
{
wordRe keyre("y.*", wordRe::REGEX);
Info<<"wordRe: " << keyre << endl;
wordRe key2(std::move(keyre));
Info<<"keyTypes: " << keyre << " " << key2 << endl;
keyre = std::move(key2);
Info<<"keyTypes: " << keyre << " " << key2 << endl;
wordRe key3;
keyre.swap(key3);
Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << endl;
keyre = std::move(key3);
Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << endl;
return 0;
}
wordRes wrelist(wordrelist);
Info<< "re-list:" << wrelist() << endl;
......@@ -76,7 +126,7 @@ int main(int argc, char *argv[])
wre = "this .* file";
Info<<"substring: " << wre(4) << endl;
Info<<"substring: " << wre.substr(4) << endl;
wre.info(Info) << endl;
wre = s1;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -113,6 +113,9 @@ public:
//- Construct from string, optionally ignore case
inline regExp(const std::string& pattern, bool ignoreCase);
//- Move construct
inline regExp(regExp&& rgx);
//- Destructor
inline ~regExp();
......@@ -146,6 +149,9 @@ public:
// \return True if expression had existed prior to the clear.
bool clear();
//- Swap contents
inline void swap(regExp& rgx);
// Matching/Searching
......@@ -177,6 +183,10 @@ public:
//- Assign and compile pattern from string
// Always case sensitive
inline void operator=(const std::string& pattern);
//- Move assignment
inline void operator=(regExp&& rgx);
};
......
......@@ -23,6 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#include <algorithm>
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
......@@ -78,6 +80,14 @@ inline Foam::regExp::regExp(const std::string& pattern, bool ignoreCase)
}
inline Foam::regExp::regExp(regExp&& rgx)
:
preg_(rgx.preg_)
{
rgx.preg_ = nullptr;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
inline Foam::regExp::~regExp()
......@@ -112,6 +122,12 @@ inline bool Foam::regExp::search(const std::string& text) const
}
inline void Foam::regExp::swap(regExp& rgx)
{
std::swap(preg_, rgx.preg_);
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
inline bool Foam::regExp::operator()(const std::string& text) const
......@@ -132,4 +148,11 @@ inline void Foam::regExp::operator=(const std::string& pattern)
}
inline void Foam::regExp::operator=(regExp&& rgx)
{
clear();
swap(rgx);
}
// ************************************************************************* //
......@@ -249,6 +249,9 @@ public:
//- Append an element to the end of this list.
inline DynamicList<T, SizeMin>& append(const T& val);
//- Move append an element
inline DynamicList<T, SizeMin>& append(T&& val);
//- Append another list to the end of this list.
inline DynamicList<T, SizeMin>& append(const UList<T>& lst);
......
......@@ -492,7 +492,22 @@ Foam::DynamicList<T, SizeMin>::append
const label idx = List<T>::size();
setSize(idx + 1);
this->operator[](idx) = val;
this->operator[](idx) = val; // copy element
return *this;
}
template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>&
Foam::DynamicList<T, SizeMin>::append
(
T&& val
)
{
const label idx = List<T>::size();
setSize(idx + 1);
this->operator[](idx) = std::move(val); // move assign element
return *this;
}
......@@ -510,12 +525,13 @@ Foam::DynamicList<T, SizeMin>::append
<< "Attempted appending to self" << abort(FatalError);
}
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (const T& val : lst)
{
this->operator[](nextFree++) = val;
this->operator[](idx++) = val; // copy element
}
return *this;
}
......@@ -529,12 +545,12 @@ Foam::DynamicList<T, SizeMin>::append
const FixedList<T, FixedSize>& lst
)
{
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (const T& val : lst)
{
this->operator[](nextFree++) = val;
this->operator[](idx++) = val; // copy element
}
return *this;
}
......@@ -547,12 +563,13 @@ Foam::DynamicList<T, SizeMin>::append
std::initializer_list<T> lst
)
{
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (const T& val : lst)
{
this->operator[](nextFree++) = val;
this->operator[](idx++) = val; // copy element
}
return *this;
}
......@@ -565,12 +582,14 @@ Foam::DynamicList<T, SizeMin>::append
const UIndirectList<T>& lst
)
{
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
const label n = lst.size();
setSize(idx + n);
forAll(lst, elemI)
for (label i=0; i<n; ++i)
{
this->operator[](nextFree++) = lst[elemI];
this->operator[](idx++) = lst[i]; // copy element
}
return *this;
}
......@@ -589,12 +608,13 @@ Foam::DynamicList<T, SizeMin>::append
<< "Attempted appending to self" << abort(FatalError);
}
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (T& val : lst)
{
Foam::Swap(this->operator[](nextFree++), val);
Foam::Swap(this->operator[](idx++), val); // moved content
}
lst.clear();
......@@ -779,11 +799,13 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
const FixedList<T, FixedSize>& lst
)
{
setSize(lst.size());
const label n = lst.size();
setSize(n);
forAll(lst, i)
for (label i=0; i<n; ++i)
{
this->operator[](i) = lst[i];
this->operator[](i) = lst[i]; // copy element
}
}
......
......@@ -226,7 +226,10 @@ public:
//- Append an element at the end of the list
inline void append(const T& val);
//- Append a List at the end of this list
//- Move append an element at the end of the list
inline void append(T&& val);
//- Append a List to the end of this list
inline void append(const UList<T>& lst);
//- Append a UIndirectList at the end of this list
......
......@@ -172,7 +172,17 @@ inline Foam::Xfer<Foam::List<T>> Foam::List<T>::xfer()
template<class T>
inline void Foam::List<T>::append(const T& val)
{
setSize(this->size()+1, val);
setSize(this->size() + 1, val); // copy element
}
template<class T>
inline void Foam::List<T>::append(T&& val)
{
const label idx = this->size();
setSize(idx + 1);
this->operator[](idx) = std::move(val); // move assign element
}
......@@ -185,12 +195,14 @@ inline void Foam::List<T>::append(const UList<T>& lst)
<< "attempted appending to self" << abort(FatalError);
}
label nextFree = this->size();
setSize(nextFree + lst.size());
label idx = this->size();
const label n = lst.size();
forAll(lst, i)
setSize(idx + n);
for (label i=0; i<n; ++i)
{
this->operator[](nextFree++) = lst[i];
this->operator[](idx++) = lst[i]; // copy element
}
}
......@@ -198,12 +210,14 @@ inline void Foam::List<T>::append(const UList<T>& lst)
template<class T>
inline void Foam::List<T>::append(const UIndirectList<T>& lst)
{
label nextFree = this->size();
setSize(nextFree + lst.size());
label idx = this->size();
const label n = lst.size();
setSize(idx + n);
forAll(lst, i)
for (label i=0; i<n; ++i)
{
this->operator[](nextFree++) = lst[i];
this->operator[](idx++) = lst[i]; // copy element
}
}
......
......@@ -92,7 +92,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
}
else
{
// uniform content (delimiter == token::BEGIN_BLOCK)
// Uniform content (delimiter == token::BEGIN_BLOCK)
T element;
is >> element;
......@@ -141,7 +141,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
// Putback the opening bracket
is.putBack(firstToken);
// Now read as a singly-linked list
// Read as a singly-linked list
SLList<T> sll(is);
// Convert the singly-linked list to this list
......@@ -176,8 +176,11 @@ Foam::List<T> Foam::readList(Istream& is)
<< exit(FatalIOError);
}
// Read via a singly-linked list
L = SLList<T>(is);
// Read as singly-linked list
SLList<T> sll(is);
// Convert the singly-linked list to this list
L = sll;
}
else
{
......
......@@ -24,8 +24,9 @@ License
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "OSstream.H"
#include "token.H"
#include "OSstream.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -52,7 +53,7 @@ Foam::Ostream& Foam::OSstream::write(const char c)
os_ << c;
if (c == token::NL)
{
lineNumber_++;
++lineNumber_;
}
setState(os_.rdstate());
return *this;
......@@ -61,7 +62,7 @@ Foam::Ostream& Foam::OSstream::write(const char c)
Foam::Ostream& Foam::OSstream::write(const char* str)
{
lineNumber_ += string(str).count(token::NL);
lineNumber_ += stringOps::count(str, token::NL);
os_ << str;
setState(os_.rdstate());
return *this;
......@@ -169,7 +170,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
else
{
// output unquoted string, only advance line number on newline
lineNumber_ += string(str).count(token::NL);
lineNumber_ += stringOps::count(str, token::NL);
os_ << str;
}
......
......@@ -359,10 +359,8 @@ std::string Foam::fileName::path(const std::string& str)
{
return str.substr(0, i);
}
else
{
return "/";
}
return "/";
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -72,7 +72,7 @@ class keyType
// Private Member Functions
//- Disallow assignments where we cannot determine string/word type
//- No assignment where we cannot determine string/word type
void operator=(const std::string&) = delete;
public:
......@@ -88,22 +88,34 @@ public:
//- Construct null
inline keyType();
//- Construct as copy, retaining type (literal or regex)
//- Copy construct, retaining type (literal or regex)
inline keyType(const keyType& s);
//- Construct as copy of word. Not treated as a regular expression
//- Copy construct from word. Not treated as a regular expression
inline keyType(const word& s);
//- Construct as copy of string. Treat as regular expression.
//- Copy construct from string. Treat as regular expression.
inline keyType(const string& s);
//- Construct as copy of character array.
// Not treated as a regular expression
inline keyType(const char* s);
//- Construct as copy of std::string with specified treatment
//- Copy construct from std::string with specified treatment
inline keyType(const std::string& s, const bool isPattern);
//- Move construct, retaining type (literal or regex)
inline keyType(keyType&& s);
//- Move construct from word. Not treated as a regular expression
inline keyType(word&& s);
//- Move construct from string. Treat as regular expression.
inline keyType(string&& s);
//- Move construct from std::string with specified treatment
inline keyType(std::string&& s, const bool isPattern);
//- Construct from Istream
// Treat as regular expression if surrounded by quotation marks.
keyType(Istream& is);
......@@ -119,6 +131,9 @@ public:
//- Treat as a pattern rather than a literal string?
inline bool isPattern() const;