Compare commits
34 Commits
wip-meson-
...
feature-st
| Author | SHA1 | Date | |
|---|---|---|---|
| 775d0b277b | |||
| f7dfb02d12 | |||
| a252677618 | |||
| 99f5d9a7db | |||
| 133149a1dd | |||
| 6396256522 | |||
| 5d98eec6af | |||
| 2d76514b5b | |||
| 2e3f0811a0 | |||
| ff2abdf1f0 | |||
| f49403969e | |||
| 2e8e259217 | |||
| 0250a1b0bb | |||
| aa1b6d9cbd | |||
| df6de6ed33 | |||
| f800ccc3d9 | |||
| 459aaad0f9 | |||
| a341d09afc | |||
| 6d7e67408e | |||
| d8f5714d1b | |||
| 69169c5abe | |||
| 539d538d5a | |||
| c09acbb781 | |||
| b931772369 | |||
| 750d9084d4 | |||
| 6defeddbff | |||
| 9d291ab4cc | |||
| 0e11f47f74 | |||
| 698e05eeb3 | |||
| 2395e493d1 | |||
| 12916cd7a3 | |||
| b66369fb37 | |||
| b236e1493c | |||
| a6744d0814 |
@ -1,2 +1,2 @@
|
||||
api=2306
|
||||
api=2307
|
||||
patch=0
|
||||
|
||||
3
applications/test/ICharStream1/Make/files
Normal file
3
applications/test/ICharStream1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-ICharStream1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-ICharStream1
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,14 +27,46 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ListStream.H"
|
||||
#include "UListStream.H"
|
||||
#include "SpanStream.H"
|
||||
#include "wordList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "argList.H"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
char buf[4];
|
||||
os << list.size() << '(';
|
||||
for (const char c : list)
|
||||
{
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
os << "\\t";
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
os << "\\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
::snprintf(buf, 4, "%02X", c);
|
||||
os << "\\x" << buf;
|
||||
}
|
||||
}
|
||||
os << ')';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
@ -93,7 +125,7 @@ int main(int argc, char *argv[])
|
||||
// Buffer storage
|
||||
DynamicList<char> storage(16);
|
||||
|
||||
OListStream obuf(std::move(storage));
|
||||
OCharStream obuf(std::move(storage));
|
||||
obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
|
||||
|
||||
// Move contents to output buffer
|
||||
@ -104,9 +136,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "transfer contents to a List" << endl;
|
||||
|
||||
IListStream ibuf;
|
||||
ICharStream ibuf;
|
||||
|
||||
// Reclaim data storage from OListStream -> IListStream
|
||||
// Reclaim data storage from OCharStream -> ICharStream
|
||||
{
|
||||
List<char> data;
|
||||
obuf.swap(data);
|
||||
@ -161,6 +193,43 @@ int main(int argc, char *argv[])
|
||||
Info<<nl << "swapped out:";
|
||||
printInfo(newvalues);
|
||||
|
||||
{
|
||||
iliststream is(std::move(newvalues));
|
||||
|
||||
char c = 0;
|
||||
|
||||
Info<< nl
|
||||
<< "getting values from iliststream of "
|
||||
<< is.list() << endl;
|
||||
|
||||
// Info<< " (" << is.tellg() << " " << is.remaining() << ")";
|
||||
// Info<< "get:";
|
||||
while (is.get(c))
|
||||
{
|
||||
Info<< ' ' << c;
|
||||
// Info<< " (" << is.tellg() << " " << is.remaining() << ")";
|
||||
}
|
||||
Info<< " - end" << nl;
|
||||
|
||||
// Info<< "remaining: " << is.list() << endl;
|
||||
// Info<< "remaining: " << is.remaining() << endl;
|
||||
|
||||
// Manipulate the list view
|
||||
{
|
||||
UList<char> chars(is.list());
|
||||
Foam::reverse(chars);
|
||||
}
|
||||
|
||||
is.rewind();
|
||||
|
||||
Info<< "get:";
|
||||
while (is.get(c))
|
||||
{
|
||||
Info<< ' ' << c;
|
||||
}
|
||||
Info<< " - end" << nl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -33,6 +33,7 @@ Description
|
||||
|
||||
#include "argList.H"
|
||||
#include "Fstream.H"
|
||||
#include "OSspecific.H"
|
||||
#include "etcFiles.H"
|
||||
|
||||
using namespace Foam;
|
||||
@ -44,11 +45,14 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noParallel();
|
||||
argList::noParallel();
|
||||
argList::addOption("ignore", "file", "Test readRaw with ignore");
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
// Test with etc/controlDict (mandatory, from distribution)
|
||||
|
||||
if (!args.found("ignore"))
|
||||
{
|
||||
const fileName inputFile
|
||||
(
|
||||
@ -97,6 +101,43 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
fileName testFile;
|
||||
if (args.readIfPresent("ignore", testFile))
|
||||
{
|
||||
if (testFile.has_ext("gz"))
|
||||
{
|
||||
testFile.remove_ext();
|
||||
Info<< "stripping extraneous .gz ending" << endl;
|
||||
}
|
||||
|
||||
IFstream is(testFile);
|
||||
auto& stdStream = is.stdStream();
|
||||
|
||||
List<char> buffer(1000);
|
||||
|
||||
Info<< "Test readRaw with: " << is.name()
|
||||
<< " compressed:" << int(is.compression())
|
||||
<< " file-size:" << is.fileSize() << nl;
|
||||
|
||||
for (int iter = 0; is.good() && iter < 1000; ++iter)
|
||||
{
|
||||
Info<< "iter:" << iter;
|
||||
if (iter % 2)
|
||||
{
|
||||
Info<< " [read] ";
|
||||
is.readRaw(buffer.data(), buffer.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " [ignore]";
|
||||
is.readRaw(nullptr, buffer.size() / 2);
|
||||
}
|
||||
|
||||
Info<< " : " << stdStream.gcount() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
Test-IListStream.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-IListStream
|
||||
@ -28,8 +28,6 @@ Description
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "ListStream.H"
|
||||
#include "UListStream.H"
|
||||
#include "wordList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "argList.H"
|
||||
|
||||
@ -183,9 +183,7 @@ int main(int argc, char *argv[])
|
||||
Pout<<"recv: " << flatOutput(recv) << endl;
|
||||
}
|
||||
|
||||
// MPI barrier
|
||||
bool barrier = true;
|
||||
Pstream::broadcast(barrier);
|
||||
UPstream::barrier(UPstream::worldComm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
3
applications/test/OCharStream1/Make/files
Normal file
3
applications/test/OCharStream1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-OCharStream1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-OCharStream1
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,13 +27,46 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ListStream.H"
|
||||
#include "SpanStream.H"
|
||||
#include "wordList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "argList.H"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
char buf[4];
|
||||
os << list.size() << '(';
|
||||
for (const char c : list)
|
||||
{
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
os << "\\t";
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
os << "\\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
::snprintf(buf, 4, "%02X", c);
|
||||
os << "\\x" << buf;
|
||||
}
|
||||
}
|
||||
os << ')';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
@ -91,12 +124,12 @@ void outputDict(OS& os)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
|
||||
// Buffer storage
|
||||
DynamicList<char> storage(16);
|
||||
|
||||
OListStream obuf(std::move(storage));
|
||||
|
||||
obuf.setBlockSize(100);
|
||||
OCharStream obuf(std::move(storage));
|
||||
|
||||
printInfo(obuf);
|
||||
|
||||
@ -140,10 +173,10 @@ int main(int argc, char *argv[])
|
||||
Info<<"after overwrite" << nl;
|
||||
printInfo(obuf);
|
||||
|
||||
Info<< "transfer contents to a List or IListStream" << nl;
|
||||
Info<< "transfer contents to a List or ICharStream" << nl;
|
||||
|
||||
IListStream ibuf;
|
||||
// Reclaim data storage from OListStream -> IListStream
|
||||
ICharStream ibuf;
|
||||
// Reclaim data storage from OCharStream -> ICharStream
|
||||
{
|
||||
List<char> data;
|
||||
obuf.swap(data);
|
||||
@ -169,7 +202,7 @@ int main(int argc, char *argv[])
|
||||
Info<<"input:";
|
||||
toString(Info, list) << endl;
|
||||
|
||||
OListStream buf1(std::move(list));
|
||||
OCharStream buf1(std::move(list));
|
||||
|
||||
Info<<"orig:";
|
||||
toString(Info, list) << endl;
|
||||
@ -204,7 +237,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< nl << "Test dictionary" << nl;
|
||||
{
|
||||
OListStream os1;
|
||||
OCharStream os1;
|
||||
|
||||
outputDict(os1);
|
||||
|
||||
@ -213,7 +246,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
{
|
||||
OListStream os2;
|
||||
OCharStream os2;
|
||||
os2.indentSize(0);
|
||||
|
||||
outputDict(os2);
|
||||
@ -74,7 +74,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "counter state: " << (cnt.stdStream().rdstate()) << nl
|
||||
<< "via string-stream: " << str.str().size() << " chars" << nl
|
||||
<< "via ocountstream: " << plain.size() << " chars" << endl;
|
||||
<< "via ocountstream: " << plain.count() << " chars" << endl;
|
||||
|
||||
fileName outputName;
|
||||
args.readIfPresent("write", outputName);
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
Test-OListStream.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-OListStream
|
||||
3
applications/test/SpanStream1/Make/files
Normal file
3
applications/test/SpanStream1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-SpanStream1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-SpanStream1
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,16 +27,48 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "UListStream.H"
|
||||
#include "SpanStream.H"
|
||||
#include "wordList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "argList.H"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
char buf[4];
|
||||
os << list.size() << '(';
|
||||
for (const char c : list)
|
||||
{
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
os << "\\t";
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
os << "\\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
::snprintf(buf, 4, "%02X", c);
|
||||
os << "\\x" << buf;
|
||||
}
|
||||
}
|
||||
os << ')';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
@ -108,7 +140,7 @@ int main(int argc, char *argv[])
|
||||
// Buffer storage
|
||||
DynamicList<char> storage(1000);
|
||||
|
||||
UOListStream obuf(storage);
|
||||
OSpanStream obuf(storage);
|
||||
obuf << 1002 << "\n" << "abcd" << "\n" << "def" << "\n" << 3.14159 << ";\n";
|
||||
|
||||
obuf.print(Info);
|
||||
@ -120,7 +152,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Attach input buffer - could also do without previous resize
|
||||
{
|
||||
UIListStream ibuf(storage);
|
||||
ISpanStream ibuf(storage);
|
||||
|
||||
printTokens(ibuf);
|
||||
|
||||
@ -135,13 +167,21 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< "parse as std::istream\n";
|
||||
|
||||
uiliststream is(storage.cdata(), storage.size());
|
||||
ispanstream is(storage.cdata(), storage.size());
|
||||
|
||||
Info<< "input: ";
|
||||
writeList(Info, is.list()) << endl;
|
||||
|
||||
Info<< "where: " << is.tellg() << endl;
|
||||
Info<< "capacity: " << is.capacity() << endl;
|
||||
Info<< "total: " << is.capacity() << endl;
|
||||
|
||||
string tok;
|
||||
|
||||
while (std::getline(is, tok))
|
||||
{
|
||||
std::cerr << "tok: " << tok << nl;
|
||||
Info<< "where: " << is.tellg() << endl;
|
||||
}
|
||||
|
||||
Info<< nl << "Repeat..." << endl;
|
||||
@ -170,7 +210,7 @@ int main(int argc, char *argv[])
|
||||
toString(Info, chars);
|
||||
Info<< "----" << nl;
|
||||
|
||||
uiliststream is(chars.data(), chars.size());
|
||||
ispanstream is(chars.data(), chars.size());
|
||||
string tok;
|
||||
std::cerr<< nl << "Parsed..." << nl;
|
||||
while (std::getline(is, tok))
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,7 @@ Description
|
||||
#include "scalarField.H"
|
||||
#include "SubField.H"
|
||||
#include "labelRange.H"
|
||||
#include "ListOps.H"
|
||||
#include <numeric>
|
||||
|
||||
using namespace Foam;
|
||||
@ -57,26 +58,26 @@ int main(int argc, char *argv[])
|
||||
argList::noFunctionObjects();
|
||||
|
||||
{
|
||||
List<scalar> ident(25);
|
||||
List<label> ident(25);
|
||||
std::iota(ident.begin(), ident.end(), 0);
|
||||
|
||||
print(ident);
|
||||
|
||||
SubList<scalar>(ident, 10) = -10;
|
||||
SubList<label>(ident, 10) = -10;
|
||||
print(ident);
|
||||
|
||||
SubField<scalar>(ident, 10) = 10;
|
||||
SubField<label>(ident, 10) = 10;
|
||||
print(ident);
|
||||
|
||||
SubField<scalar>(ident, 10) += 10;
|
||||
SubField<label>(ident, 10) += 10;
|
||||
print(ident);
|
||||
|
||||
SubField<scalar>{ident, 10, 10} *= 5;
|
||||
SubField<label>{ident, 10, 10} *= 5;
|
||||
print(ident);
|
||||
|
||||
|
||||
// NOTE: Need {} instead of ()
|
||||
// SubList<scalar>(ident) = 100;
|
||||
// SubList<label>(ident) = 100;
|
||||
|
||||
// GCC
|
||||
// error: conflicting declaration 'Foam::SubList<double> ident'
|
||||
@ -85,7 +86,30 @@ int main(int argc, char *argv[])
|
||||
// warning: parentheses were disambiguated as redundant parentheses
|
||||
// around declaration of variable named 'ident' [-Wvexing-parse]
|
||||
|
||||
SubList<scalar>{ident} = 100;
|
||||
SubList<label>{ident} = 100;
|
||||
print(ident);
|
||||
|
||||
SubList<label> sub(ident);
|
||||
sub = 1;
|
||||
print(sub);
|
||||
|
||||
sub.reset(ident, labelRange(4, 5)) = 5;
|
||||
print(sub);
|
||||
print(ident);
|
||||
|
||||
sub.reset(ident, labelRange(14, 5)) = 15;
|
||||
print(sub);
|
||||
print(ident);
|
||||
|
||||
// Cryptic, probably not a great idea to write this
|
||||
sub.reset(ident, {20, 3}) = -1;
|
||||
print(sub);
|
||||
print(ident);
|
||||
|
||||
// This is also possible since we hold a concrete pointer/size
|
||||
// and not an intermediate
|
||||
ListOps::identity(sub.reset(ident, 8, 8));
|
||||
print(sub);
|
||||
print(ident);
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
Test-UIListStream.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-UIListStream
|
||||
@ -204,7 +204,7 @@ int main(int argc, char *argv[])
|
||||
labelPair inOut;
|
||||
pointField allCcs(globalNumbering.gather(mesh.cellCentres()));
|
||||
inOut[0] = allCcs.size();
|
||||
Pstream::broadcast(allCcs);
|
||||
Pstream::broadcastList(allCcs);
|
||||
inOut[1] = allCcs.size();
|
||||
Pout<< " " << inOut << endl;
|
||||
|
||||
|
||||
@ -68,25 +68,51 @@ int main(int argc, char *argv[])
|
||||
labelRange::debug = 1;
|
||||
}
|
||||
|
||||
Info<< nl;
|
||||
{
|
||||
labelRange range(5, 10);
|
||||
Info<< "identity: " << identity(range) << nl;
|
||||
}
|
||||
|
||||
{
|
||||
Info<<"test sorting" << endl;
|
||||
DynamicList<labelRange> list1(10);
|
||||
Info<< "test sorting" << endl;
|
||||
labelRanges list1(10);
|
||||
|
||||
list1.emplace_back(25, 8);
|
||||
list1.emplace_back(8);
|
||||
list1.emplace_back(15, 5);
|
||||
list1.emplace_back(50, -10, true);
|
||||
|
||||
sort(list1);
|
||||
Info<<"sorted" << list1 << endl;
|
||||
// Move construct
|
||||
labelRanges ranges(std::move(list1));
|
||||
if (!list1.empty())
|
||||
{
|
||||
Info<< "Move construct failed? "
|
||||
<< flatOutput(list1.ranges()) << nl;
|
||||
}
|
||||
|
||||
Info<< "unsorted: ";
|
||||
ranges.writeList(Info) << nl;
|
||||
|
||||
ranges.sort();
|
||||
Info<< "sorted: ";
|
||||
ranges.writeList(Info) << nl;
|
||||
|
||||
Info<< nl
|
||||
<< "list linear length = " << ranges.totalSize() << nl;
|
||||
|
||||
Info<< "list labels = ";
|
||||
ranges.labels().writeList(Info) << nl;
|
||||
|
||||
Info<< nl;
|
||||
for (int i : { -1, 0, 5, 8, 10, 20, 26 })
|
||||
{
|
||||
Info<< "value at [" << i << "] = " << ranges[i] << nl;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Info<<"test intersections" << endl;
|
||||
Info<< "test intersections" << endl;
|
||||
labelRange range1(-15, 25);
|
||||
labelRange range2(7, 8);
|
||||
labelRange range3(-20, 8);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -75,6 +75,16 @@ void testBroadcast(List<T>& values)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void testBroadcast(std::vector<T>& values)
|
||||
{
|
||||
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
|
||||
Pout<< "pre-broadcast: " << flatOutput(values) << endl;
|
||||
Pstream::broadcast(values);
|
||||
Pout<< "post-broadcast: " << flatOutput(values) << endl;
|
||||
}
|
||||
|
||||
|
||||
void testBroadcast(bitSet& values)
|
||||
{
|
||||
Pout<< "pre-broadcast: "
|
||||
@ -135,6 +145,20 @@ int main(int argc, char *argv[])
|
||||
testBroadcast(values);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<word> values;
|
||||
if (Pstream::master())
|
||||
{
|
||||
values.resize(UPstream::nProcs());
|
||||
|
||||
for (decltype(values.size()) i=0; i < values.size(); ++i)
|
||||
{
|
||||
values[i] = "vector_" + Foam::name(i);
|
||||
}
|
||||
}
|
||||
testBroadcast(values);
|
||||
}
|
||||
|
||||
{
|
||||
vector values(vector::uniform(-1));
|
||||
if (Pstream::master())
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -33,7 +33,7 @@ Description
|
||||
|
||||
#include "scalar.H"
|
||||
#include "FlatOutput.H"
|
||||
#include "ListStream.H"
|
||||
#include "SpanStream.H"
|
||||
#include "StringStream.H"
|
||||
#include "NASCore.H"
|
||||
#include "parsing.H"
|
||||
@ -443,22 +443,22 @@ int main(int argc, char *argv[])
|
||||
<< " read " << sizeof(scalar) << nl;
|
||||
|
||||
List<otherType> srcList(15);
|
||||
|
||||
forAll(srcList, i)
|
||||
{
|
||||
srcList[i] = 1 + 10*i;
|
||||
}
|
||||
|
||||
DynamicList<char> buf;
|
||||
|
||||
OListStream os(std::move(buf), IOstreamOption::BINARY);
|
||||
OCharStream os(IOstreamOption::BINARY);
|
||||
os << srcList;
|
||||
|
||||
os.swap(buf); // Recover buffer
|
||||
DynamicList<char> buf;
|
||||
os.swap(buf); // Recover written contents
|
||||
|
||||
// Read back
|
||||
List<scalar> dstList;
|
||||
|
||||
UIListStream is(buf, IOstreamOption::BINARY);
|
||||
ISpanStream is(buf, IOstreamOption::BINARY);
|
||||
is.setScalarByteSize(sizeof(otherType));
|
||||
|
||||
Info<< "Stream scalar-size ("
|
||||
|
||||
3
applications/test/readBroadcast1/Make/files
Normal file
3
applications/test/readBroadcast1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-readBroadcast1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-readBroadcast1
|
||||
2
applications/test/readBroadcast1/Make/options
Normal file
2
applications/test/readBroadcast1/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
297
applications/test/readBroadcast1/Test-readBroadcast1.C
Normal file
297
applications/test/readBroadcast1/Test-readBroadcast1.C
Normal file
@ -0,0 +1,297 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2023 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/>.
|
||||
|
||||
Description
|
||||
Test file reading with broadcast
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "OSspecific.H" // For fileSize()
|
||||
#include "Fstream.H"
|
||||
#include "Pstream.H"
|
||||
#include "SpanStream.H"
|
||||
#include <limits>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
bool optUseSeek = false;
|
||||
bool optVerbose = false;
|
||||
|
||||
// Get file contents. Usually master-only and broadcast
|
||||
static List<char> slurpFile
|
||||
(
|
||||
const fileName& pathname,
|
||||
const bool parallel = UPstream::parRun(),
|
||||
const bool masterOnly = true
|
||||
)
|
||||
{
|
||||
Info<< "slurp master-only:" << masterOnly
|
||||
<< " broadcast:" << (masterOnly && parallel)
|
||||
<< " seek:" << optUseSeek
|
||||
<< " file: " << pathname << nl;
|
||||
|
||||
if (optUseSeek)
|
||||
{
|
||||
Info<< "Rewinding gzstream does not work..." << nl;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
|
||||
List<char> buffer;
|
||||
|
||||
ifstreamPointer ifp;
|
||||
|
||||
if (UPstream::master() || !masterOnly)
|
||||
{
|
||||
ifp.open(pathname);
|
||||
}
|
||||
|
||||
if (ifp && ifp->good())
|
||||
{
|
||||
Info<< "compressed:"
|
||||
<< (IOstreamOption::COMPRESSED == ifp.whichCompression()) << nl;
|
||||
|
||||
#if 0
|
||||
uint64_t inputSize = Foam::fileSize(pathname);
|
||||
|
||||
if (IOstreamOption::COMPRESSED == ifp.whichCompression())
|
||||
{
|
||||
ifp->ignore(std::numeric_limits<std::streamsize>::max());
|
||||
|
||||
const std::streamsize nread = ifp->gcount();
|
||||
|
||||
if (nread == std::numeric_limits<std::streamsize>::max())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Failed call to ignore()" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
inputSize = ifp->gcount();
|
||||
|
||||
if (optUseSeek)
|
||||
{
|
||||
// Rewinding gzstream does not really work...
|
||||
ifp->rdbuf()->pubseekpos(0, std::ios_base::in);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Open it again - gzstream rewinding is unreliable...
|
||||
ifp.open(pathname);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.resize(label(inputSize));
|
||||
ifp->read(buffer.data(), buffer.size_bytes());
|
||||
|
||||
const std::streamsize nread = ifp->gcount();
|
||||
|
||||
if (nread == std::numeric_limits<std::streamsize>::max())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Failed call to read()" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
buffer.resize(label(nread)); // Extra safety (paranoid)
|
||||
|
||||
#else
|
||||
|
||||
if (IOstreamOption::COMPRESSED == ifp.whichCompression())
|
||||
{
|
||||
// For compressed files we do not have any idea how large
|
||||
// the result will be. So read chunk-wise.
|
||||
// Using the compressed size for the chunk size:
|
||||
// 50% compression = 2 iterations
|
||||
// 66% compression = 3 iterations
|
||||
// ...
|
||||
|
||||
const auto inputSize = Foam::fileSize(pathname + ".gz");
|
||||
|
||||
const uint64_t chunkSize =
|
||||
(
|
||||
(inputSize <= 1024)
|
||||
? uint64_t(4096)
|
||||
: uint64_t(2*inputSize)
|
||||
);
|
||||
|
||||
uint64_t beg = 0;
|
||||
|
||||
bool normalExit = false;
|
||||
|
||||
for (int iter = 1; iter < 100000; ++iter)
|
||||
{
|
||||
if (optVerbose)
|
||||
{
|
||||
Info<< "iter " << iter << nl;
|
||||
Info<< "chunk " << label(chunkSize) << nl;
|
||||
Info<< "size " << label(iter * chunkSize) << nl;
|
||||
}
|
||||
|
||||
buffer.resize(label(iter * chunkSize));
|
||||
ifp->read(buffer.data() + beg, chunkSize);
|
||||
|
||||
const std::streamsize nread = ifp->gcount();
|
||||
|
||||
if (optVerbose)
|
||||
{
|
||||
Info<< "nread: " << nread << nl;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
nread < 0
|
||||
|| nread == std::numeric_limits<std::streamsize>::max()
|
||||
)
|
||||
{
|
||||
if (iter == 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Failed call to read()" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
beg += uint64_t(nread);
|
||||
if (nread >= 0 && uint64_t(nread) < chunkSize)
|
||||
{
|
||||
normalExit = true;
|
||||
if (optVerbose)
|
||||
{
|
||||
Info<< "stopped after "
|
||||
<< iter << " iterations" << nl;
|
||||
}
|
||||
buffer.resize(label(beg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!normalExit)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Abnormal exit" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto inputSize = Foam::fileSize(pathname);
|
||||
|
||||
if (inputSize >= 0)
|
||||
{
|
||||
buffer.resize(label(inputSize));
|
||||
ifp->read(buffer.data(), buffer.size_bytes());
|
||||
|
||||
const std::streamsize nread = ifp->gcount();
|
||||
|
||||
if
|
||||
(
|
||||
nread < 0
|
||||
|| nread == std::numeric_limits<std::streamsize>::max()
|
||||
)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Failed call to read()" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
buffer.resize(label(nread)); // Extra safety (paranoid)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Done with input file
|
||||
ifp.reset(nullptr);
|
||||
|
||||
if (parallel && masterOnly)
|
||||
{
|
||||
// On the assumption of larger files,
|
||||
// prefer two broadcasts instead of serialization
|
||||
Pstream::broadcastList(buffer);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noFunctionObjects();
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addBoolOption("seek", "seek with gzstream (fails!)");
|
||||
argList::addVerboseOption("addition information");
|
||||
argList::addBoolOption("seek", "seek with gzstream");
|
||||
argList::addBoolOption("no-broadcast", "suppress broadcast contents");
|
||||
|
||||
argList::addNote("Test master-only reading (with broadcast)");
|
||||
|
||||
argList::addArgument("srcFile");
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
const bool syncPar = (UPstream::parRun() && !args.found("no-broadcast"));
|
||||
optUseSeek = args.found("seek");
|
||||
optVerbose = args.verbose();
|
||||
|
||||
auto srcName = args.get<fileName>(1);
|
||||
|
||||
if (srcName.has_ext("gz"))
|
||||
{
|
||||
srcName.remove_ext();
|
||||
Info<< "stripping extraneous .gz ending" << endl;
|
||||
}
|
||||
|
||||
ICharStream is;
|
||||
|
||||
{
|
||||
List<char> buffer(slurpFile(srcName, syncPar));
|
||||
|
||||
is.swap(buffer);
|
||||
}
|
||||
|
||||
Pout<< "input:" << is.capacity() << endl;
|
||||
|
||||
for (string line; is.getLine(line); /*nil*/)
|
||||
{
|
||||
Pout<< "L:" << is.lineNumber() << ": " << line.c_str() << nl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -51,13 +51,30 @@ int main(int argc, char *argv[])
|
||||
hmm.source()[1] = vector(1.0, 4.0, 3.0);
|
||||
hmm.source()[2] = vector(0.0, 5.0, 2.0);
|
||||
|
||||
Info<< hmm << endl;
|
||||
Info<< hmm.solve() << endl;
|
||||
Info<< hmm << endl;
|
||||
Info<< hmm.LUsolve() << endl;
|
||||
Info<< hmm << endl;
|
||||
Info<< hmm << nl;
|
||||
Info<< hmm.solve() << nl;
|
||||
Info<< hmm << nl;
|
||||
Info<< hmm.LUsolve() << nl;
|
||||
Info<< hmm << nl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
{
|
||||
scalarSquareMatrix mat0;
|
||||
Info<< "empty: " << mat0 << endl;
|
||||
|
||||
mat0.resize_nocopy(1);
|
||||
mat0 = Identity<scalar>();
|
||||
Info<< "ident (1x1): " << mat0 << endl;
|
||||
|
||||
mat0.resize_nocopy(3);
|
||||
mat0 = Identity<scalar>();
|
||||
Info<< "ident (3x3): " << mat0 << endl;
|
||||
|
||||
mat0.resize_nocopy(5);
|
||||
mat0 = Identity<scalar>();
|
||||
Info<< "ident (5x5): " << mat0 << endl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,7 +47,7 @@ Description
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "cellSet.H"
|
||||
#include "SortableList.H"
|
||||
#include "SortList.H"
|
||||
#include "labelIOList.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
@ -128,71 +128,54 @@ int main(int argc, char *argv[])
|
||||
|
||||
const scalarField& vols = mesh.cellVolumes();
|
||||
|
||||
SortableList<scalar> sortedVols(vols);
|
||||
SortList<scalar> sortedVols(vols);
|
||||
|
||||
// All cell labels, sorted per bin.
|
||||
DynamicList<DynamicList<label>> bins;
|
||||
|
||||
// Lower/upper limits
|
||||
DynamicList<scalar> lowerLimits;
|
||||
DynamicList<scalar> upperLimits;
|
||||
DynamicList<scalarMinMax> limits;
|
||||
|
||||
// Create bin0. Have upperlimit as factor times lowerlimit.
|
||||
bins.append(DynamicList<label>());
|
||||
lowerLimits.append(sortedVols[0]);
|
||||
upperLimits.append(1.1 * lowerLimits.last());
|
||||
bins.emplace_back();
|
||||
limits.emplace_back(sortedVols[0], 1.1*sortedVols[0]);
|
||||
|
||||
forAll(sortedVols, i)
|
||||
{
|
||||
if (sortedVols[i] > upperLimits.last())
|
||||
if (sortedVols[i] > limits.back().max())
|
||||
{
|
||||
// New value outside of current bin
|
||||
|
||||
// Shrink old bin.
|
||||
DynamicList<label>& bin = bins.last();
|
||||
|
||||
bin.shrink();
|
||||
|
||||
Info<< "Collected " << bin.size() << " elements in bin "
|
||||
<< lowerLimits.last() << " .. "
|
||||
<< upperLimits.last() << endl;
|
||||
Info<< "Collected " << bins.back() << " elements in bin "
|
||||
<< limits.back().min() << " .. "
|
||||
<< limits.back().max() << endl;
|
||||
|
||||
// Create new bin.
|
||||
bins.append(DynamicList<label>());
|
||||
lowerLimits.append(sortedVols[i]);
|
||||
upperLimits.append(1.1 * lowerLimits.last());
|
||||
bins.emplace_back();
|
||||
limits.emplace_back(sortedVols[i], 1.1 * sortedVols[i]);
|
||||
|
||||
Info<< "Creating new bin " << lowerLimits.last()
|
||||
<< " .. " << upperLimits.last()
|
||||
<< endl;
|
||||
Info<< "Creating new bin "
|
||||
<< limits.back().min() << " .. "
|
||||
<< limits.back().max() << endl;
|
||||
}
|
||||
|
||||
// Append to current bin.
|
||||
DynamicList<label>& bin = bins.last();
|
||||
|
||||
bin.append(sortedVols.indices()[i]);
|
||||
// Add to current bin.
|
||||
bins.back().push_back(sortedVols.indices()[i]);
|
||||
}
|
||||
Info<< endl;
|
||||
|
||||
bins.last().shrink();
|
||||
bins.shrink();
|
||||
lowerLimits.shrink();
|
||||
upperLimits.shrink();
|
||||
|
||||
|
||||
//
|
||||
// Write to cellSets.
|
||||
//
|
||||
|
||||
Info<< "Volume bins:" << nl;
|
||||
forAll(bins, binI)
|
||||
forAll(bins, bini)
|
||||
{
|
||||
const DynamicList<label>& bin = bins[binI];
|
||||
const auto& bin = bins[bini];
|
||||
|
||||
cellSet cells(mesh, "vol" + name(binI), bin.size());
|
||||
cellSet cells(mesh, "vol" + Foam::name(bini), bin.size());
|
||||
cells.insert(bin);
|
||||
|
||||
Info<< " " << lowerLimits[binI] << " .. " << upperLimits[binI]
|
||||
Info<< " " << limits[bini].min() << " .. " << limits[bini].max()
|
||||
<< " : writing " << bin.size() << " cells to cellSet "
|
||||
<< cells.name() << endl;
|
||||
|
||||
@ -294,13 +277,13 @@ int main(int argc, char *argv[])
|
||||
);
|
||||
|
||||
// Set cell values
|
||||
forAll(bins, binI)
|
||||
forAll(bins, bini)
|
||||
{
|
||||
const DynamicList<label>& bin = bins[binI];
|
||||
const auto& bin = bins[bini];
|
||||
|
||||
forAll(bin, i)
|
||||
{
|
||||
refLevel[bin[i]] = bins.size() - binI - 1;
|
||||
refLevel[bin[i]] = bins.size() - bini - 1;
|
||||
postRefLevel[bin[i]] = refLevel[bin[i]];
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,8 +468,8 @@ inline Foam::List<Foam::label> Foam::conformalVoronoiMesh::processorsAttached
|
||||
|
||||
forAll(c1Procs, aPI)
|
||||
{
|
||||
procsAttached.appendUniq(c1Procs[aPI]);
|
||||
procsAttached.appendUniq(c2Procs[aPI]);
|
||||
procsAttached.push_uniq(c1Procs[aPI]);
|
||||
procsAttached.push_uniq(c2Procs[aPI]);
|
||||
}
|
||||
|
||||
return List<label>(procsAttached);
|
||||
|
||||
@ -46,8 +46,8 @@ void Foam::shortEdgeFilter2D::assignBoundaryPointRegions
|
||||
const edge& e = iter.key();
|
||||
const label regi = iter.val();
|
||||
|
||||
boundaryPointRegions[e.start()].appendUniq(regi);
|
||||
boundaryPointRegions[e.end()].appendUniq(regi);
|
||||
boundaryPointRegions[e.first()].push_uniq(regi);
|
||||
boundaryPointRegions[e.second()].push_uniq(regi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ void Foam::shortEdgeFilter2D::updateEdgeRegionMap
|
||||
const edgeList& edges = surfMesh.edges();
|
||||
const labelList& meshPoints = surfMesh.meshPoints();
|
||||
|
||||
patchSizes.setSize(patchNames_.size(), 0);
|
||||
patchSizes.resize_nocopy(patchNames_.size());
|
||||
patchSizes = 0;
|
||||
|
||||
forAll(edges, edgeI)
|
||||
@ -78,15 +78,13 @@ void Foam::shortEdgeFilter2D::updateEdgeRegionMap
|
||||
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
const label startI = meshPoints[e[0]];
|
||||
const label endI = meshPoints[e[1]];
|
||||
|
||||
label region = -1;
|
||||
|
||||
const DynamicList<label> startPtRegions =
|
||||
boundaryPtRegions[surfPtToBoundaryPt[startI]];
|
||||
const DynamicList<label> endPtRegions =
|
||||
boundaryPtRegions[surfPtToBoundaryPt[endI]];
|
||||
const DynamicList<label>& startPtRegions =
|
||||
boundaryPtRegions[surfPtToBoundaryPt[meshPoints[e.first()]]];
|
||||
|
||||
const DynamicList<label>& endPtRegions =
|
||||
boundaryPtRegions[surfPtToBoundaryPt[meshPoints[e.second()]]];
|
||||
|
||||
if (startPtRegions.size() > 1 && endPtRegions.size() > 1)
|
||||
{
|
||||
|
||||
@ -87,11 +87,7 @@ label addPatch
|
||||
)
|
||||
);
|
||||
auto& pp = *ppPtr;
|
||||
|
||||
if (!groupName.empty())
|
||||
{
|
||||
pp.inGroups().appendUniq(groupName);
|
||||
}
|
||||
pp.addGroup(groupName);
|
||||
|
||||
|
||||
// Add patch, create calculated everywhere
|
||||
|
||||
@ -148,21 +148,15 @@ void matchPatchFaces
|
||||
// Mesh 0
|
||||
//~~~~~~~
|
||||
|
||||
interfaceMesh0.append(labelList());
|
||||
auto& intMesh0 = interfaceMesh0.last();
|
||||
intMesh0.setSize(nSourcei, -1);
|
||||
auto& intMesh0 = interfaceMesh0.emplace_back(nSourcei, -1);
|
||||
intMesh0[sourcei] = meshi;
|
||||
|
||||
interfaceSource0.append(sourcei);
|
||||
interfaceSource0.push_back(sourcei);
|
||||
|
||||
interfacePatch0.append(labelList());
|
||||
auto& intPatch0 = interfacePatch0.last();
|
||||
intPatch0.setSize(nSourcei, -1);
|
||||
auto& intPatch0 = interfacePatch0.emplace_back(nSourcei, -1);
|
||||
intPatch0[sourcei] = ppi.index();
|
||||
|
||||
interfaceNames0.append(wordList());
|
||||
auto& intNames0 = interfaceNames0.last();
|
||||
intNames0.setSize(nSourcei);
|
||||
auto& intNames0 = interfaceNames0.emplace_back(nSourcei);
|
||||
intNames0[sourcei] =
|
||||
patchName(entryName, meshes[meshi], meshes[meshj]);
|
||||
|
||||
@ -170,33 +164,23 @@ void matchPatchFaces
|
||||
// Mesh 1
|
||||
//~~~~~~~
|
||||
|
||||
interfaceMesh1.append(labelList());
|
||||
auto& intMesh1 = interfaceMesh1.last();
|
||||
intMesh1.setSize(nSourcej, -1);
|
||||
auto& intMesh1 = interfaceMesh1.emplace_back(nSourcej, -1);
|
||||
intMesh1[sourcej] = meshj;
|
||||
|
||||
interfaceSource1.append(sourcej);
|
||||
interfaceSource1.push_back(sourcej);
|
||||
|
||||
interfacePatch1.append(labelList());
|
||||
auto& intPatch1 = interfacePatch1.last();
|
||||
intPatch1.setSize(nSourcej, -1);
|
||||
auto& intPatch1 = interfacePatch1.emplace_back(nSourcej, -1);
|
||||
intPatch1[sourcej] = ppj.index();
|
||||
|
||||
interfaceNames1.append(wordList());
|
||||
auto& intNames1 = interfaceNames1.last();
|
||||
intNames1.setSize(nSourcej);
|
||||
auto& intNames1 = interfaceNames1.emplace_back(nSourcej);
|
||||
intNames1[sourcej] =
|
||||
patchName(entryName, meshes[meshj], meshes[meshi]);
|
||||
|
||||
interfaceFaces0.append(List<DynamicList<label>>());
|
||||
auto& intFaces0 = interfaceFaces0.last();
|
||||
intFaces0.setSize(nSourcei);
|
||||
auto& intFaces0 = interfaceFaces0.emplace_back(nSourcei);
|
||||
DynamicList<label>& faces0 = intFaces0[sourcei];
|
||||
faces0.setCapacity(ppi.size());
|
||||
|
||||
interfaceFaces1.append(List<DynamicList<label>>());
|
||||
auto& intFaces1 = interfaceFaces1.last();
|
||||
intFaces1.setSize(nSourcej);
|
||||
auto& intFaces1 = interfaceFaces1.emplace_back(nSourcej);
|
||||
DynamicList<label>& faces1 = intFaces1[sourcej];
|
||||
faces1.setCapacity(ppj.size());
|
||||
|
||||
@ -249,7 +233,7 @@ void matchPatchFaces
|
||||
{
|
||||
if (weights[facei] > 0.5 || sourceMask[facei] > SMALL)
|
||||
{
|
||||
faces0.append(ppi.start()+facei);
|
||||
faces0.push_back(ppi.start()+facei);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,7 +243,7 @@ void matchPatchFaces
|
||||
{
|
||||
if (weights[facei] > 0.5 || targetMask[facei] > SMALL)
|
||||
{
|
||||
faces1.append(ppj.start()+facei);
|
||||
faces1.push_back(ppj.start()+facei);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -825,7 +809,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (pDict.get<word>("constructFrom") == "autoPatch")
|
||||
{
|
||||
interRegionSources[meshi].append(sourcei);
|
||||
interRegionSources[meshi].push_back(sourcei);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,7 +518,7 @@ void Foam::meshDualiser::createFacesAroundEdge
|
||||
|
||||
if (startDual != -1)
|
||||
{
|
||||
verts.appendUniq(startDual);
|
||||
verts.push_uniq(startDual);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -429,7 +429,7 @@ unset cmd
|
||||
|
||||
case "$WM_MPLIB" in
|
||||
*OPENMPI*)
|
||||
cmd="mpirun -app $PWD/mpirun.schema </dev/null"
|
||||
cmd="mpirun --oversubscribe -app $PWD/mpirun.schema </dev/null"
|
||||
;;
|
||||
MPICH)
|
||||
cmd="mpiexec"
|
||||
|
||||
@ -304,16 +304,21 @@ runApplication()
|
||||
#
|
||||
runParallel()
|
||||
{
|
||||
local appName appRun optValue logFile logMode nProcs
|
||||
local appName appRun optValue logFile logMode
|
||||
local mpiopts nProcs
|
||||
|
||||
# Any additional parsed arguments (eg, decomposeParDict)
|
||||
local appArgs="-parallel"
|
||||
|
||||
local mpirun="mpirun"
|
||||
if [ "$FOAM_MPI" = msmpi ]
|
||||
then
|
||||
case "$FOAM_MPI" in
|
||||
(msmpi*)
|
||||
mpirun="mpiexec"
|
||||
fi
|
||||
;;
|
||||
(*openmpi*)
|
||||
mpiopts="--oversubscribe"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Parse options until executable is encountered
|
||||
while [ "$#" -gt 0 ] && [ -z "$appRun" ]
|
||||
@ -378,11 +383,11 @@ runParallel()
|
||||
if [ "$logMode" = append ]
|
||||
then
|
||||
(
|
||||
$mpirun -n $nProcs $appRun $appArgs "$@" </dev/null >> $logFile 2>&1
|
||||
"$mpirun" $mpiopts -n "${nProcs:?}" $appRun $appArgs "$@" </dev/null >> $logFile 2>&1
|
||||
)
|
||||
else
|
||||
(
|
||||
$mpirun -n $nProcs $appRun $appArgs "$@" </dev/null > $logFile 2>&1
|
||||
"$mpirun" $mpiopts -n "${nProcs:?}" $appRun $appArgs "$@" </dev/null > $logFile 2>&1
|
||||
)
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -225,6 +225,8 @@ castellatedMeshControls
|
||||
//cellZone sphere;
|
||||
//cellZoneInside inside; // outside/insidePoint
|
||||
//insidePoint (1 1 1); // if (cellZoneInside == insidePoint)
|
||||
// or alternative multiple insidePoints:
|
||||
//insidePoints ((1 1 1)); // if (cellZoneInside == insidePoint)
|
||||
|
||||
//- Optional specification of what to do with faceZone faces:
|
||||
// internal : keep them as internal faces (default)
|
||||
|
||||
Submodule modules/visualization updated: 8c0c81f563...87886a1c8a
@ -497,7 +497,7 @@ bool Foam::fileMonitor::removeWatch(const label watchFd)
|
||||
<< watchFile_[watchFd] << endl;
|
||||
}
|
||||
|
||||
freeWatchFds_.appendUniq(watchFd);
|
||||
freeWatchFds_.push_uniq(watchFd);
|
||||
|
||||
return watcher_->removeWatch(watchFd);
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2011 Symscape
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,6 +36,7 @@ License
|
||||
#include "Switch.H"
|
||||
|
||||
#include <float.h> // For *fp functions
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
// File-local functions
|
||||
@ -98,18 +99,7 @@ void Foam::sigFpe::sigHandler(int)
|
||||
|
||||
Foam::sigFpe::sigFpe()
|
||||
{
|
||||
set(false);
|
||||
}
|
||||
|
||||
|
||||
Foam::sigFpe::ignore::ignore()
|
||||
:
|
||||
wasActive_(sigFpe::active())
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
sigFpe::unset();
|
||||
}
|
||||
set(false); // false = non-verbose
|
||||
}
|
||||
|
||||
|
||||
@ -117,28 +107,12 @@ Foam::sigFpe::ignore::ignore()
|
||||
|
||||
Foam::sigFpe::~sigFpe()
|
||||
{
|
||||
unset(false);
|
||||
}
|
||||
|
||||
|
||||
Foam::sigFpe::ignore::~ignore()
|
||||
{
|
||||
restore();
|
||||
unset(false); // false = non-verbose
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::sigFpe::ignore::restore()
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
sigFpe::set();
|
||||
}
|
||||
wasActive_ = false;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::sigFpe::requested()
|
||||
{
|
||||
return isTrue("FOAM_SIGFPE", switchFpe_);
|
||||
@ -153,8 +127,8 @@ void Foam::sigFpe::set(bool verbose)
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "trapFpe: Floating point exception trapping ";
|
||||
Info<< "- disabled on this platform" << endl;
|
||||
Info<< "trapFpe: Floating point exception trapping "
|
||||
<< "- disabled on this platform" << endl;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -194,7 +168,7 @@ void Foam::sigFpe::set(bool verbose)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "setNaN : Initialise allocated memory to NaN "
|
||||
Info<< "setNaN : Fill allocated memory with NaN "
|
||||
<< "- not supported on this platform" << endl;
|
||||
}
|
||||
}
|
||||
@ -222,9 +196,37 @@ void Foam::sigFpe::unset(bool verbose)
|
||||
}
|
||||
|
||||
|
||||
void Foam::sigFpe::fillNan(char* buf, size_t count)
|
||||
{
|
||||
if (!buf || !count) return;
|
||||
|
||||
// Fill with signaling_NaN
|
||||
const scalar val = std::numeric_limits<scalar>::signaling_NaN();
|
||||
|
||||
// Can dispatch with
|
||||
// - std::execution::parallel_unsequenced_policy
|
||||
// - std::execution::unsequenced_policy
|
||||
std::fill_n
|
||||
(
|
||||
reinterpret_cast<scalar*>(buf), (count/sizeof(scalar)), val
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void Foam::sigFpe::fillNan(UList<scalar>& list)
|
||||
{
|
||||
list = std::numeric_limits<scalar>::signaling_NaN();
|
||||
if (list.empty()) return;
|
||||
|
||||
// Fill with signaling_NaN
|
||||
const scalar val = std::numeric_limits<scalar>::signaling_NaN();
|
||||
|
||||
// Can dispatch with
|
||||
// - std::execution::parallel_unsequenced_policy
|
||||
// - std::execution::unsequenced_policy
|
||||
std::fill_n
|
||||
(
|
||||
list.data(), list.size(), val
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -57,7 +57,7 @@ SourceFiles
|
||||
#ifndef Foam_sigFpe_H
|
||||
#define Foam_sigFpe_H
|
||||
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <cstddef> // For std::size_t
|
||||
#include "scalarFwd.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -87,7 +87,7 @@ class sigFpe
|
||||
//- Floating point trapping currently active?
|
||||
static bool sigActive_;
|
||||
|
||||
//- Flag to indicate mallocNan is currently active
|
||||
//- Is NaN memory initialisation currently active?
|
||||
static bool nanActive_;
|
||||
|
||||
|
||||
@ -124,18 +124,21 @@ public:
|
||||
//- True if NaN memory initialisation is currently active.
|
||||
static bool nanActive() noexcept { return nanActive_; }
|
||||
|
||||
//- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
|
||||
// Fill memory with NaN when FOAM_SETNAN is %set
|
||||
//- Activate SIGFPE handler when FOAM_SIGFPE is enabled.
|
||||
//- Activate fill memory with signaling_NaN when FOAM_SETNAN is enabled
|
||||
static void set(bool verbose=false);
|
||||
|
||||
//- Deactivate SIGFPE signal handler and NaN memory initialisation
|
||||
//- Deactivate SIGFPE handler and NaN memory initialisation
|
||||
static void unset(bool verbose=false);
|
||||
|
||||
//- Fill data block with NaN values
|
||||
//- Fill data block with signaling_NaN values
|
||||
static void fillNan(char* buf, size_t count);
|
||||
|
||||
//- Fill data block with signaling_NaN values
|
||||
static void fillNan(UList<scalar>& list);
|
||||
|
||||
|
||||
// Helper classes
|
||||
// Helpers
|
||||
|
||||
//- Helper to locally ignore SIGFPE handling.
|
||||
// Restores the original state of the SIGFPE handler on destruction.
|
||||
@ -144,29 +147,46 @@ public:
|
||||
//- The signal handler state when entering
|
||||
bool wasActive_;
|
||||
|
||||
public:
|
||||
|
||||
//- No copy construct
|
||||
ignore(const ignore&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const ignore&) = delete;
|
||||
|
||||
//- No move construct
|
||||
ignore(ignore&&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const ignore&) = delete;
|
||||
|
||||
//- No move assignment
|
||||
void operator=(ignore&&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Constructor deactivates any previously active SIGFPE handler
|
||||
ignore();
|
||||
ignore()
|
||||
:
|
||||
wasActive_(Foam::sigFpe::active())
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
Foam::sigFpe::unset();
|
||||
}
|
||||
}
|
||||
|
||||
//- Destructor restores the original state of SIGFPE handler
|
||||
~ignore();
|
||||
~ignore() { reset(); }
|
||||
|
||||
//- Restore the original state of SIGFPE handler
|
||||
void restore();
|
||||
void reset()
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
wasActive_ = false;
|
||||
Foam::sigFpe::set();
|
||||
}
|
||||
}
|
||||
|
||||
//- Same as reset()
|
||||
void restore() { reset(); }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
sigStopAtWriteNow();
|
||||
sigStopAtWriteNow() noexcept = default;
|
||||
|
||||
//- Construct with Time reference
|
||||
explicit sigStopAtWriteNow(const Time& runTime, bool verbose=false);
|
||||
|
||||
@ -493,7 +493,7 @@ bool Foam::fileMonitor::removeWatch(const label watchFd)
|
||||
<< watchFile_[watchFd] << endl;
|
||||
}
|
||||
|
||||
freeWatchFds_.appendUniq(watchFd);
|
||||
freeWatchFds_.push_uniq(watchFd);
|
||||
|
||||
return watcher_->removeWatch(watchFd);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -33,12 +33,12 @@ License
|
||||
#include "IOstreams.H"
|
||||
#include "UList.H"
|
||||
#include "Switch.H"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
// File-local functions
|
||||
#include "signalMacros.C"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#if defined(__linux__) && defined(__GNUC__)
|
||||
#ifndef __USE_GNU
|
||||
#define __USE_GNU // To use feenableexcept()
|
||||
@ -85,32 +85,32 @@ extern "C"
|
||||
{
|
||||
extern void* __libc_malloc(size_t size);
|
||||
|
||||
// Override the GLIBC malloc to support mallocNan
|
||||
// Override the GLIBC malloc to support filling with NaN
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
// Call the low-level GLIBC malloc function
|
||||
void* ptr = __libc_malloc(size);
|
||||
|
||||
if (Foam::sigFpe::nanActive())
|
||||
{
|
||||
return Foam::sigFpe::mallocNan(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return __libc_malloc(size);
|
||||
// Fill with signaling_NaN
|
||||
const auto val = std::numeric_limits<Foam::scalar>::signaling_NaN();
|
||||
|
||||
// Can dispatch with
|
||||
// - std::execution::parallel_unsequenced_policy
|
||||
// - std::execution::unsequenced_policy
|
||||
std::fill_n
|
||||
(
|
||||
reinterpret_cast<Foam::scalar*>(ptr),
|
||||
(size/sizeof(Foam::scalar)),
|
||||
val
|
||||
);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
} // End extern C
|
||||
|
||||
|
||||
void* Foam::sigFpe::mallocNan(size_t size)
|
||||
{
|
||||
// Call the low-level GLIBC malloc function
|
||||
void* result = __libc_malloc(size);
|
||||
|
||||
// Initialize to signalling NaN
|
||||
UList<scalar> list(reinterpret_cast<scalar*>(result), size/sizeof(scalar));
|
||||
sigFpe::fillNan(list);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
|
||||
@ -134,18 +134,7 @@ void Foam::sigFpe::sigHandler(int)
|
||||
|
||||
Foam::sigFpe::sigFpe()
|
||||
{
|
||||
set(false);
|
||||
}
|
||||
|
||||
|
||||
Foam::sigFpe::ignore::ignore()
|
||||
:
|
||||
wasActive_(sigFpe::active())
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
sigFpe::unset();
|
||||
}
|
||||
set(false); // false = non-verbose
|
||||
}
|
||||
|
||||
|
||||
@ -153,28 +142,12 @@ Foam::sigFpe::ignore::ignore()
|
||||
|
||||
Foam::sigFpe::~sigFpe()
|
||||
{
|
||||
unset(false);
|
||||
}
|
||||
|
||||
|
||||
Foam::sigFpe::ignore::~ignore()
|
||||
{
|
||||
restore();
|
||||
unset(false); // false = non-verbose
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::sigFpe::ignore::restore()
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
sigFpe::set();
|
||||
}
|
||||
wasActive_ = false;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::sigFpe::requested()
|
||||
{
|
||||
return isTrue("FOAM_SIGFPE", switchFpe_);
|
||||
@ -224,7 +197,7 @@ void Foam::sigFpe::set(bool verbose)
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "setNaN : Initialise allocated memory to NaN ";
|
||||
Info<< "setNaN : Fill allocated memory with NaN ";
|
||||
|
||||
if (nanActive_)
|
||||
{
|
||||
@ -275,9 +248,37 @@ void Foam::sigFpe::unset(bool verbose)
|
||||
}
|
||||
|
||||
|
||||
void Foam::sigFpe::fillNan(char* buf, size_t count)
|
||||
{
|
||||
if (!buf || !count) return;
|
||||
|
||||
// Fill with signaling_NaN
|
||||
const auto val = std::numeric_limits<scalar>::signaling_NaN();
|
||||
|
||||
// Can dispatch with
|
||||
// - std::execution::parallel_unsequenced_policy
|
||||
// - std::execution::unsequenced_policy
|
||||
std::fill_n
|
||||
(
|
||||
reinterpret_cast<scalar*>(buf), (count/sizeof(scalar)), val
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void Foam::sigFpe::fillNan(UList<scalar>& list)
|
||||
{
|
||||
list = std::numeric_limits<scalar>::signaling_NaN();
|
||||
if (list.empty()) return;
|
||||
|
||||
// Fill with signaling_NaN
|
||||
const auto val = std::numeric_limits<scalar>::signaling_NaN();
|
||||
|
||||
// Can dispatch with
|
||||
// - std::execution::parallel_unsequenced_policy
|
||||
// - std::execution::unsequenced_policy
|
||||
std::fill_n
|
||||
(
|
||||
list.data(), list.size(), val
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -57,7 +57,7 @@ SourceFiles
|
||||
#ifndef Foam_sigFpe_H
|
||||
#define Foam_sigFpe_H
|
||||
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <cstddef> // For std::size_t
|
||||
#include "scalarFwd.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -87,7 +87,7 @@ class sigFpe
|
||||
//- Floating point trapping currently active?
|
||||
static bool sigActive_;
|
||||
|
||||
//- Flag to indicate mallocNan is currently active
|
||||
//- Is NaN memory initialisation currently active?
|
||||
static bool nanActive_;
|
||||
|
||||
|
||||
@ -124,23 +124,21 @@ public:
|
||||
//- True if NaN memory initialisation is currently active.
|
||||
static bool nanActive() noexcept { return nanActive_; }
|
||||
|
||||
//- Activate SIGFPE signal handler when FOAM_SIGFPE is %set
|
||||
// Fill memory with NaN when FOAM_SETNAN is %set
|
||||
//- Activate SIGFPE handler when FOAM_SIGFPE is enabled.
|
||||
//- Activate fill memory with signaling_NaN when FOAM_SETNAN is enabled
|
||||
static void set(bool verbose=false);
|
||||
|
||||
//- Deactivate SIGFPE signal handler and NaN memory initialisation
|
||||
//- Deactivate SIGFPE handler and NaN memory initialisation
|
||||
static void unset(bool verbose=false);
|
||||
|
||||
#ifdef __linux__
|
||||
//- Malloc function which initializes to NaN
|
||||
static void* mallocNan(size_t size);
|
||||
#endif
|
||||
//- Fill data block with signaling_NaN values
|
||||
static void fillNan(char* buf, size_t count);
|
||||
|
||||
//- Fill data block with NaN values
|
||||
//- Fill data block with signaling_NaN values
|
||||
static void fillNan(UList<scalar>& list);
|
||||
|
||||
|
||||
// Helper classes
|
||||
// Helpers
|
||||
|
||||
//- Helper to locally ignore SIGFPE handling.
|
||||
// Restores the original state of the SIGFPE handler on destruction.
|
||||
@ -149,29 +147,46 @@ public:
|
||||
//- The signal handler state when entering
|
||||
bool wasActive_;
|
||||
|
||||
public:
|
||||
|
||||
//- No copy construct
|
||||
ignore(const ignore&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const ignore&) = delete;
|
||||
|
||||
//- No move construct
|
||||
ignore(ignore&&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const ignore&) = delete;
|
||||
|
||||
//- No move assignment
|
||||
void operator=(ignore&&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Constructor deactivates any previously active SIGFPE handler
|
||||
ignore();
|
||||
ignore()
|
||||
:
|
||||
wasActive_(Foam::sigFpe::active())
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
Foam::sigFpe::unset();
|
||||
}
|
||||
}
|
||||
|
||||
//- Destructor restores the original state of SIGFPE handler
|
||||
~ignore();
|
||||
~ignore() { reset(); }
|
||||
|
||||
//- Restore the original state of SIGFPE handler
|
||||
void restore();
|
||||
void reset()
|
||||
{
|
||||
if (wasActive_)
|
||||
{
|
||||
wasActive_ = false;
|
||||
Foam::sigFpe::set();
|
||||
}
|
||||
}
|
||||
|
||||
//- Same as reset()
|
||||
void restore() { reset(); }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -271,7 +271,7 @@ gzstream = $(Streams)/gzstream
|
||||
$(gzstream)/gzstream.C
|
||||
|
||||
memstream = $(Streams)/memory
|
||||
$(memstream)/ListStream.C
|
||||
$(memstream)/SpanStreams.C
|
||||
|
||||
Fstreams = $(Streams)/Fstreams
|
||||
$(Fstreams)/IFstream.C
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -102,48 +102,51 @@ bool Foam::PackedList<Width>::uniform() const
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// The value of the first element for testing
|
||||
const unsigned int val = get(0);
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
bool identical = true;
|
||||
|
||||
if (!val)
|
||||
{
|
||||
// Zero value: can just check block content directly
|
||||
// No bits set: just check there are no non-zero blocks
|
||||
// - like bitSet::none()
|
||||
identical = (-1 == first_block());
|
||||
}
|
||||
else if (val == PackedList<Width>::max_value)
|
||||
{
|
||||
// All bits set: just check there are no zero blocks
|
||||
// - like bitSet::all()
|
||||
identical = (-1 == first_not_block());
|
||||
}
|
||||
else
|
||||
{
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki = 0; identical && blocki < nblocks; ++blocki)
|
||||
if (nblocks > 1)
|
||||
{
|
||||
identical = !blocks_[blocki];
|
||||
// Fill value for complete blocks
|
||||
const unsigned int blockval = repeated_value(val);
|
||||
|
||||
// Check each complete block (nblocks-1)
|
||||
for (label blocki = 0; identical && blocki < (nblocks-1); ++blocki)
|
||||
{
|
||||
identical = (blocks_[blocki] == blockval);
|
||||
}
|
||||
}
|
||||
|
||||
return identical;
|
||||
}
|
||||
else if (nblocks > 1)
|
||||
{
|
||||
// Fill value for complete blocks
|
||||
const unsigned int blockval = repeated_value(val);
|
||||
|
||||
// Check each complete block (nblocks-1)
|
||||
for (label blocki = 0; identical && blocki < (nblocks-1); ++blocki)
|
||||
// Partial block: check manually
|
||||
for
|
||||
(
|
||||
label elemi = elem_per_block*(nblocks-1);
|
||||
identical && elemi < size();
|
||||
++elemi
|
||||
)
|
||||
{
|
||||
identical = (blocks_[blocki] == blockval);
|
||||
identical = (val == get(elemi));
|
||||
}
|
||||
}
|
||||
|
||||
// Partial block: check manually
|
||||
for
|
||||
(
|
||||
label elemi = elem_per_block*(nblocks-1);
|
||||
identical && elemi < size();
|
||||
++elemi
|
||||
)
|
||||
{
|
||||
identical = (val == get(elemi));
|
||||
}
|
||||
|
||||
return identical;
|
||||
}
|
||||
|
||||
@ -194,16 +197,20 @@ Foam::PackedList<Width>::unpack() const
|
||||
"Width of IntType is too small to hold result"
|
||||
);
|
||||
|
||||
List<IntType> output(size());
|
||||
|
||||
if (empty())
|
||||
{
|
||||
return List<IntType>(0);
|
||||
return output;
|
||||
}
|
||||
else if (uniform())
|
||||
{
|
||||
return List<IntType>(size(), static_cast<IntType>(get(0)));
|
||||
output = static_cast<IntType>(get(0));
|
||||
return output;
|
||||
}
|
||||
|
||||
List<IntType> output(size());
|
||||
// NON-UNIFORM and len > 0
|
||||
|
||||
label outi = 0;
|
||||
|
||||
// Process n-1 complete blocks
|
||||
@ -215,7 +222,7 @@ Foam::PackedList<Width>::unpack() const
|
||||
|
||||
for (unsigned nget = elem_per_block; nget; --nget, ++outi)
|
||||
{
|
||||
output[outi] = IntType(blockval & max_value);
|
||||
output[outi] = IntType(blockval & PackedList<Width>::max_value);
|
||||
blockval >>= Width;
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,6 +221,14 @@ protected:
|
||||
//- Copy assignment
|
||||
inline void copyAssign(const PackedList<Width>& rhs);
|
||||
|
||||
//- Find the first block with a '1' bit
|
||||
// \return block number or -1 for an list or if all bits are OFF.
|
||||
inline label first_block() const;
|
||||
|
||||
//- Find the first block with a '0' bit
|
||||
// \return block number or -1 for an list or if all bits are ON.
|
||||
inline label first_not_block() const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -292,7 +300,7 @@ public:
|
||||
//- Number of elements that can be stored without reallocating
|
||||
inline label capacity() const noexcept;
|
||||
|
||||
//- True if all entries have identical values, and list is non-empty
|
||||
//- True if all entries have identical values (and list is non-empty)
|
||||
bool uniform() const;
|
||||
|
||||
//- Test for equality of sizes and the bits set
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -147,6 +147,73 @@ inline void Foam::PackedList<Width>::copyAssign(const PackedList<Width>& rhs)
|
||||
}
|
||||
|
||||
|
||||
template<unsigned Width>
|
||||
inline Foam::label Foam::PackedList<Width>::first_block() const
|
||||
{
|
||||
if (size())
|
||||
{
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (blocks_[blocki])
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
template<unsigned Width>
|
||||
inline Foam::label Foam::PackedList<Width>::first_not_block() const
|
||||
{
|
||||
if (!size())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check on complement (changes 0 <-> 1).
|
||||
// If any 1's now appear, there was a 0 bit before
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
// Extra bits in the final block?
|
||||
const unsigned int off = size() % elem_per_block;
|
||||
|
||||
if (!off)
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks-1; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
|
||||
// The final block needs masking
|
||||
if (~(blocks_[nblocks-1]) & mask_lower(off))
|
||||
{
|
||||
return nblocks-1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
|
||||
@ -18,8 +18,8 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef PackedBoolList_H
|
||||
#define PackedBoolList_H
|
||||
#ifndef FoamCompat_PackedBoolList_H
|
||||
#define FoamCompat_PackedBoolList_H
|
||||
|
||||
#include "bitSet.H"
|
||||
|
||||
|
||||
@ -65,13 +65,6 @@ class bitSet
|
||||
:
|
||||
public PackedList<1>
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Find the first block with a '0' bit
|
||||
// \return block number or -1 if the set is empty or all bits are on.
|
||||
inline label first_not_block() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Logic/Set Operations
|
||||
@ -138,7 +131,7 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Default construct an empty, zero-sized bitSet
|
||||
inline bitSet() noexcept;
|
||||
inline constexpr bitSet() noexcept;
|
||||
|
||||
//- Construct from Istream
|
||||
explicit bitSet(Istream& is);
|
||||
@ -246,9 +239,6 @@ public:
|
||||
// \note Method name compatibility with boost::dynamic_bitset
|
||||
inline bool none() const;
|
||||
|
||||
//- True if all entries have identical values, and the set is non-empty
|
||||
inline bool uniform() const;
|
||||
|
||||
//- Count number of bits set.
|
||||
// \param on can be set to false to count the number of unset bits
|
||||
// instead.
|
||||
|
||||
@ -25,56 +25,9 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
inline Foam::label Foam::bitSet::first_not_block() const
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use complement to change 0 <-> 1 and check if any 1's now appear
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
// Extra bits in the final block?
|
||||
const unsigned int off = size() % elem_per_block;
|
||||
|
||||
if (!off)
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks-1; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
|
||||
// The final block needs masking
|
||||
if (~(blocks_[nblocks-1]) & mask_lower(off))
|
||||
{
|
||||
return nblocks-1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::bitSet::bitSet() noexcept
|
||||
inline constexpr Foam::bitSet::bitSet() noexcept
|
||||
:
|
||||
PackedList<1>()
|
||||
{}
|
||||
@ -313,14 +266,14 @@ inline Foam::bitSet::const_iterator Foam::bitSet::cend() const noexcept
|
||||
|
||||
inline Foam::label Foam::bitSet::find_first() const
|
||||
{
|
||||
// Process block-wise, detecting any '1' bits
|
||||
const label blocki = first_block();
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki = 0; blocki < nblocks; ++blocki)
|
||||
if (blocki >= 0)
|
||||
{
|
||||
label pos = (blocki * elem_per_block);
|
||||
|
||||
// Detect first '1' bit within the block
|
||||
|
||||
for
|
||||
(
|
||||
unsigned int blockval = blocks_[blocki];
|
||||
@ -348,7 +301,7 @@ inline Foam::label Foam::bitSet::find_first_not() const
|
||||
{
|
||||
label pos = (blocki * elem_per_block);
|
||||
|
||||
// Detect first '0' bit by checking the complement.
|
||||
// Detect first '0' bit within the block (check the complement)
|
||||
|
||||
// No special masking for the final block, that was already checked
|
||||
// in the first_not_block() call.
|
||||
@ -461,39 +414,19 @@ inline const Foam::bitSet& Foam::bitSet::null()
|
||||
inline bool Foam::bitSet::all() const
|
||||
{
|
||||
if (empty()) return true; // SIC. boost convention
|
||||
|
||||
return -1 == first_not_block();
|
||||
return (-1 == first_not_block());
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::bitSet::any() const
|
||||
{
|
||||
if (size())
|
||||
{
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (blocks_[blocki])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return (-1 != first_block());
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::bitSet::none() const
|
||||
{
|
||||
return !any();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::bitSet::uniform() const
|
||||
{
|
||||
return (size() == 1 || (size() > 1 && (test(0) ? all() : none())));
|
||||
return (-1 == first_block());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -108,6 +108,8 @@ const Foam::SubList<T> Foam::CircularBuffer<T>::array_two() const
|
||||
template<class T>
|
||||
Foam::label Foam::CircularBuffer<T>::find(const T& val, label pos) const
|
||||
{
|
||||
if (pos < 0) return -1; // no-op
|
||||
|
||||
label i = -1;
|
||||
|
||||
const auto list1 = this->array_one();
|
||||
|
||||
@ -282,18 +282,21 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- True if the value is contained in the list.
|
||||
inline bool contains(const T& val) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Stack-like Operations
|
||||
|
||||
@ -524,8 +527,8 @@ public:
|
||||
//FOAM_DEPRECATED_FOR(2022-10, "push_back()")
|
||||
void append(const UList<T>& list) { this->push_back(list); }
|
||||
|
||||
//- Append an element if not already in the buffer.
|
||||
//FOAM_DEPRECATED_FOR(2022-10, "push_uniq()")
|
||||
//- Same as push_uniq()
|
||||
FOAM_DEPRECATED_STRICT(2022-10, "push_uniq()")
|
||||
label appendUniq(const T& val) { return this->push_uniq(val); }
|
||||
};
|
||||
|
||||
|
||||
@ -255,6 +255,13 @@ inline void Foam::CircularBuffer<T>::reserve_nocopy(const label len)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::CircularBuffer<T>::contains(const T& val) const
|
||||
{
|
||||
return (this->array_one().contains(val) || this->array_two().contains(val));
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::CircularBuffer<T>::contains(const T& val, label pos) const
|
||||
{
|
||||
|
||||
@ -499,8 +499,12 @@ bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
|
||||
{
|
||||
iterator iter(find(key));
|
||||
return iterator_erase(iter);
|
||||
if (size_)
|
||||
{
|
||||
iterator iter(find(key));
|
||||
if (iter.good()) return iterator_erase(iter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -31,13 +31,21 @@ template<class T, class Addr>
|
||||
Foam::label Foam::IndirectListBase<T, Addr>::find
|
||||
(
|
||||
const T& val,
|
||||
label pos
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
const label len = addr_.size();
|
||||
|
||||
if (pos >= 0 && len)
|
||||
if (pos >= 0 && pos < addr_.size())
|
||||
{
|
||||
// Change sub-length to (one-past) end position
|
||||
// len == -1 (like std::string::npos) - search until end
|
||||
|
||||
if (len > 0) len += pos;
|
||||
if (len < 0 || len > addr_.size())
|
||||
{
|
||||
len = addr_.size();
|
||||
}
|
||||
|
||||
const T* const vals = values_.begin();
|
||||
|
||||
while (pos < len)
|
||||
@ -62,7 +70,7 @@ Foam::label Foam::IndirectListBase<T, Addr>::rfind
|
||||
label pos
|
||||
) const
|
||||
{
|
||||
// pos == -1 has same meaning as std::string::npos - search from end
|
||||
// pos == -1 (like std::string::npos) - search from end
|
||||
|
||||
if (pos < 0 || pos >= addr_.size())
|
||||
{
|
||||
|
||||
@ -179,11 +179,19 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (default: 0, no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0, label len = -1) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \return -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (default: 0, no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos = 0, label len = -1) const;
|
||||
|
||||
//- Find index of the last occurrence of the value.
|
||||
// Any occurrences after the end pos are ignored.
|
||||
@ -191,12 +199,6 @@ public:
|
||||
// \return -1 if not found.
|
||||
label rfind(const T& val, label pos = -1) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
|
||||
@ -102,10 +102,11 @@ template<class T, class Addr>
|
||||
inline bool Foam::IndirectListBase<T, Addr>::contains
|
||||
(
|
||||
const T& val,
|
||||
label pos
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
return (this->find(val, pos) >= 0);
|
||||
return (this->find(val, pos, len) >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -443,8 +443,8 @@ public:
|
||||
this->push_back(std::move(list));
|
||||
}
|
||||
|
||||
//- Append an element if not already in the list.
|
||||
//FOAM_DEPRECATED_FOR(2022-10, "push_uniq()")
|
||||
//- Same as push_uniq()
|
||||
FOAM_DEPRECATED_STRICT(2022-10, "push_uniq()")
|
||||
label appendUniq(const T& val) { return this->push_uniq(val); }
|
||||
};
|
||||
|
||||
|
||||
@ -222,6 +222,27 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (std::is_same<char, T>::value)
|
||||
{
|
||||
// Special treatment for char data (always binary and contiguous)
|
||||
// (see List<char>::readList)
|
||||
|
||||
if (len)
|
||||
{
|
||||
const auto oldFmt = is.format(IOstreamOption::BINARY);
|
||||
|
||||
// read(...) includes surrounding start/end delimiters
|
||||
is.read(list.data_bytes(), list.size_bytes());
|
||||
|
||||
is.format(oldFmt);
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"DynamicList<char>::readList(Istream&) : "
|
||||
"reading binary block"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Begin of contents marker
|
||||
|
||||
@ -46,24 +46,42 @@ std::streamsize Foam::FixedList<T, N>::byteSize()
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, unsigned N>
|
||||
Foam::label Foam::FixedList<T, N>::find(const T& val, label pos) const
|
||||
Foam::label Foam::FixedList<T, N>::find(const T& val) const
|
||||
{
|
||||
if (pos >= 0)
|
||||
const auto iter = std::find(this->cbegin(), this->cend(), val);
|
||||
return (iter != this->cend() ? label(iter - this->cbegin()) : label(-1));
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned N>
|
||||
Foam::label Foam::FixedList<T, N>::find
|
||||
(
|
||||
const T& val,
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
if (pos >= 0 && pos < label(N))
|
||||
{
|
||||
// auto iter = std::find(this->begin(pos), this->end(), val);
|
||||
// if (iter != this->end())
|
||||
// {
|
||||
// return label(iter - this->begin());
|
||||
// }
|
||||
// Change sub-length to (one-past) end position
|
||||
// len == -1 (like std::string::npos) - search until end
|
||||
|
||||
while (pos < label(N))
|
||||
if (len > 0) len += pos;
|
||||
if (len < 0 || len > label(N))
|
||||
{
|
||||
if (this->v_[pos] == val)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
len = label(N);
|
||||
}
|
||||
|
||||
++pos;
|
||||
const auto iter = std::find
|
||||
(
|
||||
(this->cbegin() + pos),
|
||||
(this->cbegin() + len),
|
||||
val
|
||||
);
|
||||
|
||||
if (iter != (this->cbegin() + len))
|
||||
{
|
||||
return label(iter - this->cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +92,8 @@ Foam::label Foam::FixedList<T, N>::find(const T& val, label pos) const
|
||||
template<class T, unsigned N>
|
||||
Foam::label Foam::FixedList<T, N>::rfind(const T& val, label pos) const
|
||||
{
|
||||
// pos == -1 has same meaning as std::string::npos - search from end
|
||||
// pos == -1 (like std::string::npos) - search from end
|
||||
|
||||
if (pos < 0 || pos >= label(N))
|
||||
{
|
||||
pos = label(N)-1;
|
||||
|
||||
@ -275,11 +275,27 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- True if the value is contained in the list.
|
||||
inline bool contains(const T& val) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \return -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
// \param val The value to search for
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the last occurrence of the value.
|
||||
// Any occurrences after the end pos are ignored.
|
||||
@ -287,12 +303,6 @@ public:
|
||||
// \return position in list or -1 if not found.
|
||||
label rfind(const T& val, label pos = -1) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
|
||||
@ -307,9 +307,22 @@ inline bool Foam::FixedList<T, N>::uniform() const
|
||||
|
||||
|
||||
template<class T, unsigned N>
|
||||
inline bool Foam::FixedList<T, N>::contains(const T& val, label pos) const
|
||||
inline bool Foam::FixedList<T, N>::contains(const T& val) const
|
||||
{
|
||||
return (this->find(val, pos) >= 0);
|
||||
const auto iter = std::find(this->cbegin(), this->cend(), val);
|
||||
return (iter != this->cend());
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned N>
|
||||
inline bool Foam::FixedList<T, N>::contains
|
||||
(
|
||||
const T& val,
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
return (this->find(val, pos, len) >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -395,8 +395,8 @@ public:
|
||||
this->push_back(list);
|
||||
}
|
||||
|
||||
//- Append an element if not already in the list.
|
||||
//FOAM_DEPRECATED_FOR(2022-10, "push_uniq()")
|
||||
//- Same as push_uniq()
|
||||
FOAM_DEPRECATED_STRICT(2022-10, "push_uniq()")
|
||||
label appendUniq(const T& val) { return this->push_uniq(val); }
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -89,7 +89,10 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Construct from UList, the entire size
|
||||
inline explicit SubList(const UList<T>& list);
|
||||
inline explicit SubList(const UList<T>& list) noexcept;
|
||||
|
||||
//- Construct from std::vector, the entire size
|
||||
inline explicit SubList(const std::vector<T>& list) noexcept;
|
||||
|
||||
//- Construct from FixedList, the entire size
|
||||
template<unsigned N>
|
||||
@ -128,6 +131,47 @@ public:
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Reset to zero-sized and nullptr
|
||||
inline UList<T>& reset(std::nullptr_t) noexcept;
|
||||
|
||||
//- Reset to use entire UList
|
||||
inline UList<T>& reset(const UList<T>& list) noexcept;
|
||||
|
||||
//- Reset to use UList with sub-list size, start at 0
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize
|
||||
);
|
||||
|
||||
//- Reset to use UList with sub-list size and start index
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize,
|
||||
const label startIndex
|
||||
);
|
||||
|
||||
//- Reset to use UList with a (start,size) range.
|
||||
// The range is subsetted with the list size itself to ensure that the
|
||||
// result always addresses a valid section of the list.
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const labelRange& range
|
||||
);
|
||||
|
||||
//- Reset to use UList with a (start,size) range, but bypassing
|
||||
//- run-time range checking.
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const labelRange& range,
|
||||
const UList<T>& list
|
||||
);
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Allow cast to a const List\<T\>&
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,18 +28,37 @@ License
|
||||
|
||||
#include "FixedList.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline const Foam::SubList<T>& Foam::SubList<T>::null()
|
||||
{
|
||||
return NullObjectRef<SubList<T>>();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline Foam::SubList<T>::SubList
|
||||
(
|
||||
const UList<T>& list
|
||||
)
|
||||
) noexcept
|
||||
:
|
||||
UList<T>(const_cast<T*>(list.cdata()), list.size())
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::SubList<T>::SubList
|
||||
(
|
||||
const std::vector<T>& list
|
||||
) noexcept
|
||||
:
|
||||
UList<T>(const_cast<T*>(list.data()), label(list.size()))
|
||||
{}
|
||||
|
||||
|
||||
template<class T>
|
||||
template<unsigned N>
|
||||
inline Foam::SubList<T>::SubList
|
||||
@ -113,9 +132,102 @@ inline Foam::SubList<T>::SubList
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline const Foam::SubList<T>& Foam::SubList<T>::null()
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset(std::nullptr_t) noexcept
|
||||
{
|
||||
return NullObjectRef<SubList<T>>();
|
||||
UList<T>::shallowCopy(nullptr, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list
|
||||
) noexcept
|
||||
{
|
||||
UList<T>::shallowCopy(list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
list.checkSize(subSize);
|
||||
#endif
|
||||
|
||||
UList<T>::shallowCopy(const_cast<T*>(list.cdata()), subSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize,
|
||||
const label startIndex
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
list.checkRange(startIndex, subSize);
|
||||
#endif
|
||||
|
||||
UList<T>::shallowCopy
|
||||
(
|
||||
const_cast<T*>(list.cdata() + startIndex),
|
||||
subSize
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const labelRange& range
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
// subset0() always produces valid ranges but want to check
|
||||
// that the input itself was valid
|
||||
list.checkRange(range.start(), range.size());
|
||||
#endif
|
||||
|
||||
labelRange clamped(range.subset0(list.size()));
|
||||
|
||||
UList<T>::shallowCopy
|
||||
(
|
||||
const_cast<T*>(list.cdata() + clamped.start()),
|
||||
clamped.size()
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const labelRange& range,
|
||||
const UList<T>& list
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
list.checkRange(range.start(), range.size());
|
||||
#endif
|
||||
|
||||
UList<T>::shallowCopy
|
||||
(
|
||||
const_cast<T*>(list.cdata() + range.start()),
|
||||
range.size()
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -177,26 +177,37 @@ std::streamsize Foam::UList<T>::byteSize() const
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::label Foam::UList<T>::find(const T& val, label pos) const
|
||||
Foam::label Foam::UList<T>::find(const T& val) const
|
||||
{
|
||||
const label len = this->size();
|
||||
const auto iter = std::find(this->cbegin(), this->cend(), val);
|
||||
return (iter != this->cend() ? label(iter - this->cbegin()) : label(-1));
|
||||
}
|
||||
|
||||
if (pos >= 0)
|
||||
|
||||
template<class T>
|
||||
Foam::label Foam::UList<T>::find(const T& val, label pos, label len) const
|
||||
{
|
||||
if (pos >= 0 && pos < this->size())
|
||||
{
|
||||
// auto iter = std::find(this->begin(pos), this->end(), val);
|
||||
// if (iter != this->end())
|
||||
// {
|
||||
// return label(iter - this->begin());
|
||||
// }
|
||||
// Change sub-length to (one-past) end position
|
||||
// len == -1 (like std::string::npos) - search until end
|
||||
|
||||
while (pos < len)
|
||||
if (len > 0) len += pos;
|
||||
if (len < 0 || len > this->size())
|
||||
{
|
||||
if (this->v_[pos] == val)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
len = this->size();
|
||||
}
|
||||
|
||||
++pos;
|
||||
const auto iter = std::find
|
||||
(
|
||||
(this->cbegin() + pos),
|
||||
(this->cbegin() + len),
|
||||
val
|
||||
);
|
||||
|
||||
if (iter != (this->cbegin() + len))
|
||||
{
|
||||
return label(iter - this->cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +218,8 @@ Foam::label Foam::UList<T>::find(const T& val, label pos) const
|
||||
template<class T>
|
||||
Foam::label Foam::UList<T>::rfind(const T& val, label pos) const
|
||||
{
|
||||
// pos == -1 has same meaning as std::string::npos - search from end
|
||||
// pos == -1 (like std::string::npos) - search from end
|
||||
|
||||
if (pos < 0 || pos >= this->size())
|
||||
{
|
||||
pos = this->size()-1;
|
||||
|
||||
@ -318,11 +318,27 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- True if the value is contained in the list.
|
||||
inline bool contains(const T& val) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \param val The value to search for
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
label find(const T& val) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the last occurrence of the value.
|
||||
// Any occurrences after the end pos are ignored.
|
||||
@ -330,12 +346,6 @@ public:
|
||||
// \return position in list or -1 if not found.
|
||||
label rfind(const T& val, label pos = -1) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
@ -354,6 +364,9 @@ public:
|
||||
|
||||
// Copy
|
||||
|
||||
//- Copy the pointer and size
|
||||
inline void shallowCopy(T* __restrict__ ptr, const label len) noexcept;
|
||||
|
||||
//- Copy the pointer and size held by the given UList
|
||||
inline void shallowCopy(const UList<T>& list) noexcept;
|
||||
|
||||
@ -663,7 +676,11 @@ Ostream& operator<<(Ostream& os, const UList<T>& list)
|
||||
return list.writeList(os, Detail::ListPolicy::short_length<T>::value);
|
||||
}
|
||||
|
||||
//- Write std::vector to Ostream. ASCII only, no line-breaks
|
||||
//- Read std::vector contents from Istream
|
||||
template<class T>
|
||||
Istream& operator>>(Istream& is, std::vector<T>& list);
|
||||
|
||||
//- Write std::vector to Ostream (via UList)
|
||||
template<class T>
|
||||
Ostream& operator<<(Ostream& os, const std::vector<T>& list);
|
||||
|
||||
|
||||
@ -304,9 +304,29 @@ inline std::streamsize Foam::UList<T>::size_bytes() const noexcept
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::UList<T>::contains(const T& val, label pos) const
|
||||
inline bool Foam::UList<T>::contains(const T& val) const
|
||||
{
|
||||
return (this->find(val, pos) >= 0);
|
||||
const auto iter = std::find(this->begin(), this->end(), val);
|
||||
return (iter != this->end());
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::UList<T>::contains(const T& val, label pos, label len) const
|
||||
{
|
||||
return (this->find(val, pos, len) >= 0);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::UList<T>::shallowCopy
|
||||
(
|
||||
T* __restrict__ ptr,
|
||||
const label len
|
||||
) noexcept
|
||||
{
|
||||
size_ = len;
|
||||
v_ = ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -187,10 +187,7 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
list[i] = std::move(elems[i]);
|
||||
}
|
||||
std::move(elems.begin(), elems.end(), list.begin());
|
||||
}
|
||||
else if (tok.isLabel())
|
||||
{
|
||||
|
||||
@ -26,35 +26,183 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "UList.H"
|
||||
#include "Istream.H"
|
||||
#include "Ostream.H"
|
||||
#include "contiguous.H"
|
||||
#include "token.H"
|
||||
#include <vector>
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const std::vector<T>& list)
|
||||
Foam::Istream& Foam::operator>>(Istream& is, std::vector<T>& list)
|
||||
{
|
||||
auto iter = list.cbegin();
|
||||
const auto last = list.cend();
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
|
||||
// Write ascii list contents, no line breaks
|
||||
token tok(is);
|
||||
|
||||
os << label(list.size()) << token::BEGIN_LIST;
|
||||
is.fatalCheck("Istream >> std::vector<T> : reading first token");
|
||||
|
||||
if (iter != last)
|
||||
if (tok.isCompound())
|
||||
{
|
||||
os << *iter;
|
||||
// No compound handling ...
|
||||
|
||||
while (++iter != last)
|
||||
list.clear(); // Clear old contents
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Support for compoundToken - not implemented" << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
else if (tok.isLabel())
|
||||
{
|
||||
// Label: could be int(..), int{...} or just a plain '0'
|
||||
|
||||
const label len = tok.labelToken();
|
||||
|
||||
// Resize to length required
|
||||
list.resize(len);
|
||||
|
||||
if (is.format() == IOstreamOption::BINARY && is_contiguous<T>::value)
|
||||
{
|
||||
os << token::SPACE << *iter;
|
||||
// Binary and contiguous
|
||||
|
||||
if (len)
|
||||
{
|
||||
Detail::readContiguous<T>
|
||||
(
|
||||
is,
|
||||
reinterpret_cast<char*>(list.data()), // data_bytes()
|
||||
std::streamsize(list.size())*sizeof(T) // size_bytes()
|
||||
);
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"Istream >> std::vector<T> : "
|
||||
"reading binary block"
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (std::is_same<char, T>::value)
|
||||
{
|
||||
// Special treatment for char data (binary I/O only)
|
||||
const auto oldFmt = is.format(IOstreamOption::BINARY);
|
||||
|
||||
if (len)
|
||||
{
|
||||
// read(...) includes surrounding start/end delimiters
|
||||
is.read
|
||||
(
|
||||
reinterpret_cast<char*>(list.data()), // data_bytes()
|
||||
std::streamsize(list.size())*sizeof(T) // size_bytes()
|
||||
);
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"Istream >> std::vector<char> : "
|
||||
"reading binary block"
|
||||
);
|
||||
}
|
||||
|
||||
is.format(oldFmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Begin of contents marker
|
||||
const char delimiter = is.readBeginList("List");
|
||||
|
||||
if (len)
|
||||
{
|
||||
if (delimiter == token::BEGIN_LIST)
|
||||
{
|
||||
auto iter = list.begin();
|
||||
const auto last = list.end();
|
||||
|
||||
// Contents
|
||||
for (/*nil*/; (iter != last); (void)++iter)
|
||||
{
|
||||
is >> *iter;
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"Istream >> std::vector<char> : "
|
||||
"reading entry"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uniform content (delimiter == token::BEGIN_BLOCK)
|
||||
|
||||
T elem;
|
||||
is >> elem;
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"Istream >> std::vector<char> : "
|
||||
"reading the single entry"
|
||||
);
|
||||
|
||||
// Fill with the value
|
||||
list.assign(list.size(), elem);
|
||||
}
|
||||
}
|
||||
|
||||
// End of contents marker
|
||||
is.readEndList("List");
|
||||
}
|
||||
}
|
||||
else if (tok.isPunctuation(token::BEGIN_LIST))
|
||||
{
|
||||
// "(...)" : read as bracketed list
|
||||
|
||||
os << token::END_LIST;
|
||||
// Slightly sub-optimal since it has intermediate resizing,
|
||||
// however don't expect this as input very often.
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
list.clear(); // Clear addressing, leave storage intact (probably)
|
||||
|
||||
is >> tok;
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
|
||||
while (!tok.isPunctuation(token::END_LIST))
|
||||
{
|
||||
is.putBack(tok);
|
||||
|
||||
// C++17
|
||||
// is >> list.emplace_back();
|
||||
|
||||
// C++11
|
||||
list.emplace_back();
|
||||
is >> list.back();
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"Istream >> std::vector<char> : "
|
||||
"reading entry"
|
||||
);
|
||||
|
||||
is >> tok;
|
||||
is.fatalCheck(FUNCTION_NAME);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.clear(); // Clear old contents
|
||||
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "incorrect first token, expected <int> or '(', found "
|
||||
<< tok.info() << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const std::vector<T>& list)
|
||||
{
|
||||
// Use UList for output
|
||||
UList<T> proxy(const_cast<T*>(list.data()), label(list.size()));
|
||||
os << proxy;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -1065,14 +1065,9 @@ void Foam::ListOps::appendEqOp<T>::operator()
|
||||
{
|
||||
if (y.size())
|
||||
{
|
||||
label len = x.size();
|
||||
if (len)
|
||||
if (x.size())
|
||||
{
|
||||
x.resize(len + y.size());
|
||||
for (const T& val : y)
|
||||
{
|
||||
x[len++] = val;
|
||||
}
|
||||
x.push_back(y);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1095,11 +1090,7 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
|
||||
{
|
||||
for (const T& val : y)
|
||||
{
|
||||
// --> x.push_uniq(val)
|
||||
if (!x.contains(val))
|
||||
{
|
||||
x.push_back(val);
|
||||
}
|
||||
x.push_uniq(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -88,6 +88,41 @@ template<> struct no_linebreak<word> : std::true_type {};
|
||||
template<> struct no_linebreak<wordRe> : std::true_type {};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Classification of list/container uniformity.
|
||||
//- The values can be used with bit-wise \c or reduction
|
||||
enum uniformity : unsigned char
|
||||
{
|
||||
EMPTY = 0, //!< An empty container
|
||||
UNIFORM = 0x1, //!< Container (non-empty) with identical values
|
||||
NONUNIFORM = 0x2, //!< Container (non-empty) with different values
|
||||
MIXED = 0x3 //!< Mixed uniform/non-uniform (eg, after reduction)
|
||||
};
|
||||
|
||||
//- Algorithm to determine list/container uniformity
|
||||
template<class InputIt>
|
||||
enum uniformity check_uniformity(InputIt first, InputIt last)
|
||||
{
|
||||
if (first == last) return uniformity::EMPTY;
|
||||
|
||||
// Like std::all_of() with checking against element 0,
|
||||
// but without using a lambda with auto type (pre C++14) etc.
|
||||
|
||||
const auto& elem0 = *first;
|
||||
|
||||
for ((void)++first; (first != last); (void)++first)
|
||||
{
|
||||
if (elem0 != *first)
|
||||
{
|
||||
return uniformity::NONUNIFORM;
|
||||
}
|
||||
}
|
||||
|
||||
return uniformity::UNIFORM;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace ListPolicy
|
||||
|
||||
@ -37,7 +37,7 @@ License
|
||||
#include "charList.H"
|
||||
#include "labelPair.H"
|
||||
#include "masterUncollatedFileOperation.H"
|
||||
#include "ListStream.H"
|
||||
#include "SpanStream.H"
|
||||
#include "StringStream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -403,7 +403,7 @@ Foam::decomposedBlockData::readBlock
|
||||
|
||||
if (blocki == 0)
|
||||
{
|
||||
realIsPtr.reset(new IListStream(std::move(data)));
|
||||
realIsPtr.reset(new ICharStream(std::move(data)));
|
||||
realIsPtr->name() = is.name();
|
||||
|
||||
{
|
||||
@ -422,7 +422,7 @@ Foam::decomposedBlockData::readBlock
|
||||
{
|
||||
{
|
||||
// Read header from first block
|
||||
UIListStream headerStream(data);
|
||||
ISpanStream headerStream(data);
|
||||
if (!headerIO.readHeader(headerStream))
|
||||
{
|
||||
FatalIOErrorInFunction(headerStream)
|
||||
@ -440,7 +440,7 @@ Foam::decomposedBlockData::readBlock
|
||||
// Read and discard data, only retain the last one
|
||||
decomposedBlockData::readBlockEntry(is, data);
|
||||
}
|
||||
realIsPtr.reset(new IListStream(std::move(data)));
|
||||
realIsPtr.reset(new ICharStream(std::move(data)));
|
||||
realIsPtr->name() = is.name();
|
||||
|
||||
// Apply stream settings
|
||||
@ -585,7 +585,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
|
||||
// Read master data
|
||||
decomposedBlockData::readBlockEntry(is, data);
|
||||
|
||||
realIsPtr.reset(new IListStream(std::move(data)));
|
||||
realIsPtr.reset(new ICharStream(std::move(data)));
|
||||
realIsPtr->name() = fName;
|
||||
|
||||
{
|
||||
@ -639,7 +639,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
|
||||
);
|
||||
is >> data;
|
||||
|
||||
realIsPtr.reset(new IListStream(std::move(data)));
|
||||
realIsPtr.reset(new ICharStream(std::move(data)));
|
||||
realIsPtr->name() = fName;
|
||||
}
|
||||
}
|
||||
@ -673,7 +673,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
|
||||
UIPstream is(UPstream::masterNo(), pBufs);
|
||||
is >> data;
|
||||
|
||||
realIsPtr.reset(new IListStream(std::move(data)));
|
||||
realIsPtr.reset(new ICharStream(std::move(data)));
|
||||
realIsPtr->name() = fName;
|
||||
}
|
||||
}
|
||||
@ -1090,7 +1090,7 @@ bool Foam::decomposedBlockData::writeData(Ostream& os) const
|
||||
// Re-read my own data to find out the header information
|
||||
if (Pstream::master(comm_))
|
||||
{
|
||||
UIListStream headerStream(contentData_);
|
||||
ISpanStream headerStream(contentData_);
|
||||
io.readHeader(headerStream);
|
||||
|
||||
verValue = headerStream.version().canonical();
|
||||
|
||||
@ -29,7 +29,7 @@ License
|
||||
#include "dictionary.H"
|
||||
#include "foamVersion.H"
|
||||
#include "objectRegistry.H"
|
||||
#include "ListStream.H"
|
||||
#include "SpanStream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
@ -125,7 +125,7 @@ bool Foam::decomposedBlockData::readHeader(IOobject& io, Istream& is)
|
||||
List<char> charData;
|
||||
decomposedBlockData::readBlockEntry(is, charData);
|
||||
|
||||
UIListStream headerStream(charData);
|
||||
ISpanStream headerStream(charData);
|
||||
headerStream.name() = is.name();
|
||||
|
||||
ok = io.readHeader(headerStream);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,7 +27,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IFstream.H"
|
||||
#include "OSspecific.H"
|
||||
#include "OSspecific.H" // For isFile(), fileSize()
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -45,7 +45,7 @@ Foam::IFstream::IFstream
|
||||
IOstreamOption streamOpt
|
||||
)
|
||||
:
|
||||
Foam::ifstreamPointer(pathname),
|
||||
Foam::ifstreamPointer(pathname, streamOpt),
|
||||
ISstream(*(ifstreamPointer::get()), pathname, streamOpt)
|
||||
{
|
||||
IOstreamOption::compression(ifstreamPointer::whichCompression());
|
||||
@ -91,6 +91,45 @@ Foam::IFstream::IFstream
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
std::streamsize Foam::IFstream::fileSize() const
|
||||
{
|
||||
const std::istream* ptr = ifstreamPointer::get();
|
||||
|
||||
if (!ptr || this->name().empty())
|
||||
{
|
||||
return std::streamsize(-1);
|
||||
}
|
||||
|
||||
off_t fileLen = -1;
|
||||
|
||||
if (IOstreamOption::COMPRESSED == ifstreamPointer::whichCompression())
|
||||
{
|
||||
fileLen = Foam::fileSize(this->name() + ".gz");
|
||||
}
|
||||
else
|
||||
{
|
||||
// TBD: special handing for wrapped icharstream
|
||||
// if
|
||||
// (
|
||||
// const Foam::icharstream* charstr
|
||||
// = dynamic_cast<const Foam::icharstream*>(ptr)>(ptr)
|
||||
// )
|
||||
// {
|
||||
// return charstr->capacity();
|
||||
// }
|
||||
|
||||
fileLen = Foam::fileSize(this->name());
|
||||
}
|
||||
|
||||
if (fileLen >= 0)
|
||||
{
|
||||
return std::streamsize(fileLen);
|
||||
}
|
||||
|
||||
return std::streamsize(-1);
|
||||
}
|
||||
|
||||
|
||||
std::istream& Foam::IFstream::stdStream()
|
||||
{
|
||||
std::istream* ptr = ifstreamPointer::get();
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -94,6 +94,13 @@ public:
|
||||
//- Read/write access to the name of the stream
|
||||
using ISstream::name;
|
||||
|
||||
//- Return the size of the underlying file (-1 on error).
|
||||
//- This corresponds to Foam::fileSize() but with extra handling of
|
||||
//- compressed files.
|
||||
// The return type is \c std::streamsize instead of \c off_t.
|
||||
// \note Use sparingly since it involves a file stat()!
|
||||
std::streamsize fileSize() const;
|
||||
|
||||
|
||||
// STL stream
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -65,7 +65,7 @@ Foam::OFstream::OFstream
|
||||
Foam::ofstreamPointer
|
||||
(
|
||||
pathname,
|
||||
streamOpt.compression(),
|
||||
streamOpt,
|
||||
(IOstreamOption::appendType::APPEND == append),
|
||||
(IOstreamOption::atomicType::ATOMIC == atomic)
|
||||
),
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -74,7 +74,7 @@ class ifstreamPointer
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The stream pointer (ifstream or igzstream)
|
||||
//- The stream pointer (ifstream | igzstream, ...)
|
||||
std::unique_ptr<std::istream> ptr_;
|
||||
|
||||
|
||||
@ -114,8 +114,20 @@ public:
|
||||
//- Construct from pathname.
|
||||
// Attempts to read the specified file.
|
||||
// If that fails, try as a compressed file (.gz ending).
|
||||
// \param pathname The file name to open for reading
|
||||
explicit ifstreamPointer(const fileName& pathname);
|
||||
|
||||
//- Construct from pathname, option.
|
||||
// Attempts to read the specified file.
|
||||
// If that fails, try as a compressed file (.gz ending).
|
||||
// \param pathname The file name to open for reading
|
||||
// \param streamOpt Currently unused
|
||||
ifstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption streamOpt
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -125,6 +137,9 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- True if it holds a valid pointer
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- The stream pointer (ifstream or igzstream)
|
||||
std::istream* get() noexcept { return ptr_.get(); }
|
||||
|
||||
@ -135,6 +150,19 @@ public:
|
||||
IOstreamOption::compressionType whichCompression() const;
|
||||
|
||||
|
||||
// Wrapped Methods
|
||||
|
||||
//- Attempts to open the specified file for reading.
|
||||
// If that fails, try as a compressed file (.gz ending).
|
||||
// \param pathname The file name to open for reading
|
||||
// \param streamOpt Currently unused
|
||||
void open
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
);
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Return managed pointer and release ownership
|
||||
@ -168,7 +196,7 @@ class ofstreamPointer
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The stream pointer (ofstream | ogzstream | ocountstream)
|
||||
//- The stream pointer (ofstream | ogzstream | ocountstream, ...)
|
||||
std::unique_ptr<std::ostream> ptr_;
|
||||
|
||||
//- Atomic file creation
|
||||
@ -211,9 +239,24 @@ public:
|
||||
//- Default construct (empty)
|
||||
ofstreamPointer() noexcept;
|
||||
|
||||
//- Construct as null output stream using Foam::ocountstream
|
||||
//- Construct as null output stream (Foam::ocountstream)
|
||||
explicit ofstreamPointer(std::nullptr_t);
|
||||
|
||||
//- Construct from pathname, option, append, file handling atomic
|
||||
// \param pathname The file name to open for writing
|
||||
// \param streamOpt Respects (UNCOMPRESSED | COMPRESSED)
|
||||
// \param append Open in append mode
|
||||
// \param atomic Write into temporary file (not target file).
|
||||
// This option should only be used with a stream wrapper
|
||||
// (eg, OFstream) that handles the final renaming.
|
||||
explicit ofstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption streamOpt = IOstreamOption(),
|
||||
const bool append = false,
|
||||
const bool atomic = false
|
||||
);
|
||||
|
||||
//- Construct from pathname, compression, append, file handling atomic
|
||||
// \param pathname The file name to open for writing
|
||||
// \param comp UNCOMPRESSED | COMPRESSED
|
||||
@ -221,10 +264,10 @@ public:
|
||||
// \param atomic Write into temporary file (not target file).
|
||||
// This option should only be used with a stream wrapper
|
||||
// (eg, OFstream) that handles the final renaming.
|
||||
explicit ofstreamPointer
|
||||
ofstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption::compressionType comp = IOstreamOption::UNCOMPRESSED,
|
||||
IOstreamOption::compressionType comp,
|
||||
const bool append = false,
|
||||
const bool atomic = false
|
||||
);
|
||||
@ -238,6 +281,9 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- True if it holds a valid pointer
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- The stream pointer (ofstream or ogzstream)
|
||||
std::ostream* get() noexcept { return ptr_.get(); }
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -60,8 +60,23 @@ bool Foam::ofstreamPointer::supports_gz()
|
||||
}
|
||||
|
||||
|
||||
// Future: List<char> slurpFile(....);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::ifstreamPointer::ifstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption streamOpt // Currently unused
|
||||
)
|
||||
:
|
||||
ptr_(nullptr)
|
||||
{
|
||||
open(pathname, streamOpt);
|
||||
}
|
||||
|
||||
|
||||
Foam::ifstreamPointer::ifstreamPointer
|
||||
(
|
||||
const fileName& pathname
|
||||
@ -69,6 +84,162 @@ Foam::ifstreamPointer::ifstreamPointer
|
||||
:
|
||||
ptr_(nullptr)
|
||||
{
|
||||
open(pathname);
|
||||
}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer() noexcept
|
||||
:
|
||||
ptr_(),
|
||||
atomic_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t)
|
||||
:
|
||||
ptr_(new Foam::ocountstream),
|
||||
atomic_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption streamOpt,
|
||||
const bool append,
|
||||
const bool atomic
|
||||
)
|
||||
:
|
||||
ptr_(nullptr),
|
||||
atomic_(atomic)
|
||||
{
|
||||
std::ios_base::openmode mode
|
||||
(
|
||||
std::ios_base::out | std::ios_base::binary
|
||||
);
|
||||
|
||||
if (append)
|
||||
{
|
||||
mode |= std::ios_base::app;
|
||||
|
||||
// Cannot append to gzstream
|
||||
streamOpt.compression(IOstreamOption::UNCOMPRESSED);
|
||||
|
||||
// Cannot use append + atomic operation, without lots of extra work
|
||||
atomic_ = false;
|
||||
}
|
||||
|
||||
|
||||
// When opening new files, remove file variants out of the way.
|
||||
// Eg, opening "file1"
|
||||
// - remove old "file1.gz" (compressed)
|
||||
// - also remove old "file1" if it is a symlink and we are not appending
|
||||
//
|
||||
// Not writing into symlinked files avoids problems with symlinked
|
||||
// initial fields (eg, 0/U -> ../0.orig/U)
|
||||
|
||||
const fileName pathname_gz(pathname + ".gz");
|
||||
const fileName pathname_tmp(pathname + "~tmp~");
|
||||
|
||||
fileName::Type fType = fileName::Type::UNDEFINED;
|
||||
|
||||
if (IOstreamOption::COMPRESSED == streamOpt.compression())
|
||||
{
|
||||
// Output compression requested.
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
// TBD:
|
||||
// atomic_ = true; // Always treat COMPRESSED like an atomic
|
||||
|
||||
const fileName& target = (atomic_ ? pathname_tmp : pathname_gz);
|
||||
|
||||
// Remove old uncompressed version (if any)
|
||||
fType = Foam::type(pathname, false);
|
||||
if (fType == fileName::SYMLINK || fType == fileName::FILE)
|
||||
{
|
||||
Foam::rm(pathname);
|
||||
}
|
||||
|
||||
// Avoid writing into symlinked files (non-append mode)
|
||||
if (!append || atomic_)
|
||||
{
|
||||
fType = Foam::type(target, false);
|
||||
if (fType == fileName::SYMLINK)
|
||||
{
|
||||
Foam::rm(target);
|
||||
}
|
||||
}
|
||||
|
||||
ptr_.reset(new ogzstream(target, mode));
|
||||
|
||||
#else /* HAVE_LIBZ */
|
||||
|
||||
streamOpt.compression(IOstreamOption::UNCOMPRESSED);
|
||||
|
||||
Warning
|
||||
<< nl
|
||||
<< "No write support for gz compressed files (libz)"
|
||||
<< " : downgraded to UNCOMPRESSED" << nl
|
||||
<< "file: " << pathname_gz << endl;
|
||||
|
||||
#endif /* HAVE_LIBZ */
|
||||
}
|
||||
|
||||
if (IOstreamOption::COMPRESSED != streamOpt.compression())
|
||||
{
|
||||
const fileName& target = (atomic_ ? pathname_tmp : pathname);
|
||||
|
||||
// Remove old compressed version (if any)
|
||||
fType = Foam::type(pathname_gz, false);
|
||||
if (fType == fileName::SYMLINK || fType == fileName::FILE)
|
||||
{
|
||||
Foam::rm(pathname_gz);
|
||||
}
|
||||
|
||||
// Avoid writing into symlinked files (non-append mode)
|
||||
if (!append || atomic_)
|
||||
{
|
||||
fType = Foam::type(target, false);
|
||||
if (fType == fileName::SYMLINK)
|
||||
{
|
||||
Foam::rm(target);
|
||||
}
|
||||
}
|
||||
|
||||
ptr_.reset(new std::ofstream(target, mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption::compressionType comp,
|
||||
const bool append,
|
||||
const bool atomic
|
||||
)
|
||||
:
|
||||
ofstreamPointer
|
||||
(
|
||||
pathname,
|
||||
IOstreamOption(IOstreamOption::ASCII, comp),
|
||||
append,
|
||||
atomic
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::ifstreamPointer::open
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption streamOpt // Currently unused
|
||||
)
|
||||
{
|
||||
// Forcibly close old stream (if any)
|
||||
ptr_.reset(nullptr);
|
||||
|
||||
const std::ios_base::openmode mode
|
||||
(
|
||||
std::ios_base::in | std::ios_base::binary
|
||||
@ -110,131 +281,6 @@ Foam::ifstreamPointer::ifstreamPointer
|
||||
}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer() noexcept
|
||||
:
|
||||
ptr_(),
|
||||
atomic_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t)
|
||||
:
|
||||
ptr_(new Foam::ocountstream),
|
||||
atomic_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::ofstreamPointer::ofstreamPointer
|
||||
(
|
||||
const fileName& pathname,
|
||||
IOstreamOption::compressionType comp,
|
||||
const bool append,
|
||||
const bool atomic
|
||||
)
|
||||
:
|
||||
ptr_(nullptr),
|
||||
atomic_(atomic)
|
||||
{
|
||||
std::ios_base::openmode mode
|
||||
(
|
||||
std::ios_base::out | std::ios_base::binary
|
||||
);
|
||||
|
||||
if (append)
|
||||
{
|
||||
mode |= std::ios_base::app;
|
||||
|
||||
// Cannot append to gzstream
|
||||
comp = IOstreamOption::UNCOMPRESSED;
|
||||
|
||||
// Cannot use append + atomic operation, without lots of extra work
|
||||
atomic_ = false;
|
||||
}
|
||||
|
||||
|
||||
// When opening new files, remove file variants out of the way.
|
||||
// Eg, opening "file1"
|
||||
// - remove old "file1.gz" (compressed)
|
||||
// - also remove old "file1" if it is a symlink and we are not appending
|
||||
//
|
||||
// Not writing into symlinked files avoids problems with symlinked
|
||||
// initial fields (eg, 0/U -> ../0.orig/U)
|
||||
|
||||
const fileName pathname_gz(pathname + ".gz");
|
||||
const fileName pathname_tmp(pathname + "~tmp~");
|
||||
|
||||
fileName::Type fType = fileName::Type::UNDEFINED;
|
||||
|
||||
if (IOstreamOption::COMPRESSED == comp)
|
||||
{
|
||||
// Output compression requested.
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
// TBD:
|
||||
// atomic_ = true; // Always treat COMPRESSED like an atomic
|
||||
|
||||
const fileName& target = (atomic_ ? pathname_tmp : pathname_gz);
|
||||
|
||||
// Remove old uncompressed version (if any)
|
||||
fType = Foam::type(pathname, false);
|
||||
if (fType == fileName::SYMLINK || fType == fileName::FILE)
|
||||
{
|
||||
Foam::rm(pathname);
|
||||
}
|
||||
|
||||
// Avoid writing into symlinked files (non-append mode)
|
||||
if (!append || atomic_)
|
||||
{
|
||||
fType = Foam::type(target, false);
|
||||
if (fType == fileName::SYMLINK)
|
||||
{
|
||||
Foam::rm(target);
|
||||
}
|
||||
}
|
||||
|
||||
ptr_.reset(new ogzstream(target, mode));
|
||||
|
||||
#else /* HAVE_LIBZ */
|
||||
|
||||
comp = IOstreamOption::UNCOMPRESSED;
|
||||
|
||||
Warning
|
||||
<< nl
|
||||
<< "No write support for gz compressed files (libz)"
|
||||
<< " : downgraded to UNCOMPRESSED" << nl
|
||||
<< "file: " << pathname_gz << endl;
|
||||
|
||||
#endif /* HAVE_LIBZ */
|
||||
}
|
||||
|
||||
if (IOstreamOption::COMPRESSED != comp)
|
||||
{
|
||||
const fileName& target = (atomic_ ? pathname_tmp : pathname);
|
||||
|
||||
// Remove old compressed version (if any)
|
||||
fType = Foam::type(pathname_gz, false);
|
||||
if (fType == fileName::SYMLINK || fType == fileName::FILE)
|
||||
{
|
||||
Foam::rm(pathname_gz);
|
||||
}
|
||||
|
||||
// Avoid writing into symlinked files (non-append mode)
|
||||
if (!append || atomic_)
|
||||
{
|
||||
fType = Foam::type(target, false);
|
||||
if (fType == fileName::SYMLINK)
|
||||
{
|
||||
Foam::rm(target);
|
||||
}
|
||||
}
|
||||
|
||||
ptr_.reset(new std::ofstream(target, mode));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::ifstreamPointer::reopen_gz(const std::string& pathname)
|
||||
{
|
||||
#ifdef HAVE_LIBZ
|
||||
|
||||
@ -102,9 +102,8 @@ public:
|
||||
//- Broadcast buffer content to all processes in communicator.
|
||||
using UPstream::broadcast;
|
||||
|
||||
//- Broadcast content (contiguous or non-contiguous)
|
||||
//- to all processes in communicator.
|
||||
// For \b non-parallel : do nothing.
|
||||
//- Broadcast content (contiguous or non-contiguous) to all
|
||||
//- communicator ranks. Does nothing in \b non-parallel.
|
||||
template<class Type>
|
||||
static void broadcast
|
||||
(
|
||||
@ -112,11 +111,22 @@ public:
|
||||
const label comm = UPstream::worldComm
|
||||
);
|
||||
|
||||
//- Broadcast multiple items to all processes in communicator.
|
||||
// For \b non-parallel : do nothing.
|
||||
//- Broadcast multiple items to all communicator ranks.
|
||||
//- Does nothing in \b non-parallel.
|
||||
template<class Type, class... Args>
|
||||
static void broadcasts(const label comm, Type& arg1, Args&&... args);
|
||||
|
||||
//- Broadcast list content (contiguous or non-contiguous) to all
|
||||
//- communicator ranks. Does nothing in \b non-parallel.
|
||||
// For contiguous list data, this avoids serialization overhead,
|
||||
// but at the expense of an additional broadcast call.
|
||||
template<class ListType>
|
||||
static void broadcastList
|
||||
(
|
||||
ListType& list,
|
||||
const label comm = UPstream::worldComm
|
||||
);
|
||||
|
||||
|
||||
// Gather
|
||||
|
||||
|
||||
@ -80,4 +80,61 @@ void Foam::Pstream::broadcasts(const label comm, Type& arg1, Args&&... args)
|
||||
}
|
||||
|
||||
|
||||
template<class ListType>
|
||||
void Foam::Pstream::broadcastList(ListType& list, const label comm)
|
||||
{
|
||||
if (is_contiguous<typename ListType::value_type>::value)
|
||||
{
|
||||
// List data are contiguous
|
||||
// 1. broadcast the size
|
||||
// 2. resize for receiver list
|
||||
// 3. broadcast contiguous contents
|
||||
|
||||
if (UPstream::is_parallel(comm))
|
||||
{
|
||||
label len(list.size());
|
||||
|
||||
UPstream::broadcast
|
||||
(
|
||||
reinterpret_cast<char*>(&len),
|
||||
sizeof(label),
|
||||
comm,
|
||||
UPstream::masterNo()
|
||||
);
|
||||
|
||||
if (UPstream::is_subrank(comm))
|
||||
{
|
||||
list.resize_nocopy(len);
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
UPstream::broadcast
|
||||
(
|
||||
list.data_bytes(),
|
||||
list.size_bytes(),
|
||||
comm,
|
||||
UPstream::masterNo()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (UPstream::is_parallel(comm))
|
||||
{
|
||||
// List data are non-contiguous - serialize/de-serialize
|
||||
|
||||
if (UPstream::master(comm))
|
||||
{
|
||||
OPBstream os(UPstream::masterNo(), comm);
|
||||
os << list;
|
||||
}
|
||||
else // UPstream::is_subrank(comm)
|
||||
{
|
||||
IPBstream is(UPstream::masterNo(), comm);
|
||||
is >> list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -1051,20 +1051,7 @@ Foam::Istream& Foam::ISstream::readRaw(char* data, std::streamsize count)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Forward seek
|
||||
// - use absolute positioning (see C++ notes about std::ifstream)
|
||||
is_.seekg(is_.tellg() + std::istream::pos_type(count));
|
||||
|
||||
// Not sure if this is needed (as per rewind)
|
||||
// some documentation indicates that ifstream needs
|
||||
// seekg with values from a tellg
|
||||
//
|
||||
// stdStream().rdbuf()->pubseekpos
|
||||
// (
|
||||
// count,
|
||||
// std::ios_base::seekdir::cur,
|
||||
// std::ios_base::in
|
||||
// );
|
||||
is_.ignore(count);
|
||||
}
|
||||
}
|
||||
syncState();
|
||||
@ -1102,8 +1089,11 @@ void Foam::ISstream::rewind()
|
||||
stdStream().clear(); // Clear the iostate error state flags
|
||||
setGood(); // Sync local copy of iostate
|
||||
|
||||
// pubseekpos() rather than seekg() so that it works with gzstream
|
||||
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
|
||||
|
||||
// NOTE: this form of rewind does not work with igzstream.
|
||||
// However, igzstream is usually wrapped as IFstream which has its
|
||||
// own dedicated rewind treatment for igzstream.
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -76,9 +76,10 @@ inline int Foam::ISstream::peek()
|
||||
inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
|
||||
{
|
||||
std::getline(is_, str, delim);
|
||||
std::streamsize count = is_.gcount();
|
||||
syncState();
|
||||
|
||||
if (delim == '\n')
|
||||
if (delim == '\n' && count > 0)
|
||||
{
|
||||
++lineNumber_;
|
||||
}
|
||||
@ -90,11 +91,10 @@ 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);
|
||||
std::streamsize count = is_.gcount();
|
||||
syncState();
|
||||
|
||||
std::streamsize count = is_.gcount();
|
||||
|
||||
if (delim == '\n' && count)
|
||||
if (delim == '\n' && count > 0)
|
||||
{
|
||||
++lineNumber_;
|
||||
}
|
||||
|
||||
@ -259,7 +259,6 @@ public:
|
||||
//- Rewind the output stream
|
||||
virtual void rewind()
|
||||
{
|
||||
// pubseekpos() instead of seekp() for symmetry with other classes
|
||||
stream_.rdbuf()->pubseekpos(0, std::ios_base::out);
|
||||
}
|
||||
|
||||
|
||||
@ -28,8 +28,8 @@ License
|
||||
|
||||
#include "error.H"
|
||||
#include "ITstream.H"
|
||||
#include "SpanStream.H"
|
||||
#include "StringStream.H"
|
||||
#include "UIListStream.H"
|
||||
#include <memory>
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -94,7 +94,7 @@ Foam::tokenList Foam::ITstream::parse
|
||||
IOstreamOption streamOpt
|
||||
)
|
||||
{
|
||||
UIListStream is(input, streamOpt);
|
||||
ISpanStream is(input, streamOpt);
|
||||
|
||||
tokenList tokens;
|
||||
parseStream(is, tokens);
|
||||
@ -108,7 +108,7 @@ Foam::tokenList Foam::ITstream::parse
|
||||
IOstreamOption streamOpt
|
||||
)
|
||||
{
|
||||
UIListStream is(input.data(), input.length(), streamOpt);
|
||||
ISpanStream is(input, streamOpt);
|
||||
|
||||
tokenList tokens;
|
||||
parseStream(is, tokens);
|
||||
@ -122,7 +122,7 @@ Foam::tokenList Foam::ITstream::parse
|
||||
IOstreamOption streamOpt
|
||||
)
|
||||
{
|
||||
UIListStream is(input, strlen(input), streamOpt);
|
||||
ISpanStream is(input, strlen(input), streamOpt);
|
||||
|
||||
tokenList tokens;
|
||||
parseStream(is, tokens);
|
||||
@ -261,7 +261,7 @@ Foam::ITstream::ITstream
|
||||
:
|
||||
ITstream(streamOpt, name)
|
||||
{
|
||||
UIListStream is(input, streamOpt);
|
||||
ISpanStream is(input, streamOpt);
|
||||
|
||||
parseStream(is, static_cast<tokenList&>(*this));
|
||||
ITstream::seek(0); // rewind(), but bypasss virtual
|
||||
@ -277,7 +277,7 @@ Foam::ITstream::ITstream
|
||||
:
|
||||
ITstream(streamOpt, name)
|
||||
{
|
||||
UIListStream is(input.data(), input.length(), streamOpt);
|
||||
ISpanStream is(input.data(), input.length(), streamOpt);
|
||||
|
||||
parseStream(is, static_cast<tokenList&>(*this));
|
||||
ITstream::seek(0); // rewind(), but bypasss virtual
|
||||
@ -293,7 +293,7 @@ Foam::ITstream::ITstream
|
||||
:
|
||||
ITstream(streamOpt, name)
|
||||
{
|
||||
UIListStream is(input, strlen(input), streamOpt);
|
||||
ISpanStream is(input, strlen(input), streamOpt);
|
||||
|
||||
parseStream(is, static_cast<tokenList&>(*this));
|
||||
ITstream::seek(0); // rewind(), but bypasss virtual
|
||||
|
||||
0
src/OpenFOAM/db/IOstreams/compat/IListStream.H
Normal file
0
src/OpenFOAM/db/IOstreams/compat/IListStream.H
Normal file
@ -4,8 +4,8 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef IStringStream_H
|
||||
#define IStringStream_H
|
||||
#ifndef FoamCompat_IStringStream_H
|
||||
#define FoamCompat_IStringStream_H
|
||||
|
||||
#include "StringStream.H"
|
||||
|
||||
10
src/OpenFOAM/db/IOstreams/compat/ListStream.H
Normal file
10
src/OpenFOAM/db/IOstreams/compat/ListStream.H
Normal file
@ -0,0 +1,10 @@
|
||||
// Compatibility include.
|
||||
|
||||
#ifndef FoamCompat_ListStream_H
|
||||
#define FoamCompat_ListStream_H
|
||||
|
||||
#include "SpanStream.H"
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
10
src/OpenFOAM/db/IOstreams/compat/OListStream.H
Normal file
10
src/OpenFOAM/db/IOstreams/compat/OListStream.H
Normal file
@ -0,0 +1,10 @@
|
||||
// Compatibility include.
|
||||
|
||||
#ifndef FoamCompat_OListStream_H
|
||||
#define FoamCompat_UListStream_H
|
||||
|
||||
#include "SpanStream.H"
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -4,8 +4,8 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef OStringStream_H
|
||||
#define OStringStream_H
|
||||
#ifndef FoamCompat_OStringStream_H
|
||||
#define FoamCompat_OStringStream_H
|
||||
|
||||
#include "StringStream.H"
|
||||
|
||||
10
src/OpenFOAM/db/IOstreams/compat/UIListStream.H
Normal file
10
src/OpenFOAM/db/IOstreams/compat/UIListStream.H
Normal file
@ -0,0 +1,10 @@
|
||||
// Compatibility include.
|
||||
|
||||
#ifndef FoamCompat_UIListStream_H
|
||||
#define FoamCompat_UIListStream_H
|
||||
|
||||
#include "SpanStream.H"
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
10
src/OpenFOAM/db/IOstreams/compat/UListStream.H
Normal file
10
src/OpenFOAM/db/IOstreams/compat/UListStream.H
Normal file
@ -0,0 +1,10 @@
|
||||
// Compatibility include.
|
||||
|
||||
#ifndef FoamCompat_UListStream_H
|
||||
#define FoamCompat_UListStream_H
|
||||
|
||||
#include "SpanStream.H"
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
10
src/OpenFOAM/db/IOstreams/compat/UOListStream.H
Normal file
10
src/OpenFOAM/db/IOstreams/compat/UOListStream.H
Normal file
@ -0,0 +1,10 @@
|
||||
// Compatibility include.
|
||||
|
||||
#ifndef FoamCompat_UOListStream_H
|
||||
#define FoamCompat_UOListStream_H
|
||||
|
||||
#include "SpanStream.H"
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -54,23 +54,21 @@ class osha1stream
|
||||
public std::ostream
|
||||
{
|
||||
//- A streambuf class for calculating SHA1 digests
|
||||
class sha1buf
|
||||
:
|
||||
public std::streambuf
|
||||
class sha1buf : public std::streambuf
|
||||
{
|
||||
//- This does all the work and has its own buffering
|
||||
SHA1 sha1_;
|
||||
|
||||
protected:
|
||||
|
||||
//- Handle overflow
|
||||
virtual int overflow(int c = EOF)
|
||||
//- Output overflow handling - append to SHA1
|
||||
virtual int overflow(int_type c = traits_type::eof())
|
||||
{
|
||||
if (c != EOF) sha1_.append(c);
|
||||
if (c != traits_type::eof()) sha1_.append(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
//- Put sequence of characters
|
||||
//- Put sequence of characters - append to SHA1
|
||||
virtual std::streamsize xsputn(const char* s, std::streamsize n)
|
||||
{
|
||||
if (n) sha1_.append(s, n);
|
||||
@ -83,10 +81,7 @@ class osha1stream
|
||||
sha1buf() = default;
|
||||
|
||||
//- Full access to the sha1
|
||||
SHA1& sha1() noexcept
|
||||
{
|
||||
return sha1_;
|
||||
}
|
||||
SHA1& sha1() noexcept { return sha1_; }
|
||||
};
|
||||
|
||||
|
||||
@ -100,25 +95,22 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
osha1stream()
|
||||
:
|
||||
std::ostream(&buf_)
|
||||
{}
|
||||
osha1stream() : std::ostream(&buf_) {}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- This hides both signatures of std::basic_ios::rdbuf()
|
||||
sha1buf* rdbuf()
|
||||
{
|
||||
return &buf_;
|
||||
}
|
||||
sha1buf* rdbuf() { return &buf_; }
|
||||
|
||||
//- Full access to the sha1
|
||||
SHA1& sha1() noexcept
|
||||
{
|
||||
return buf_.sha1();
|
||||
}
|
||||
SHA1& sha1() noexcept { return buf_.sha1(); }
|
||||
|
||||
//- Return SHA1::Digest for the data processed until now
|
||||
SHA1Digest digest() { return buf_.sha1().digest(); }
|
||||
|
||||
//- Clear the SHA1 calculation
|
||||
void reset() { buf_.sha1().clear(); }
|
||||
};
|
||||
|
||||
|
||||
@ -129,48 +121,21 @@ namespace Detail
|
||||
Class Detail::OSHA1streamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- Allocator for an osha1stream
|
||||
//- An allocator for holding Foam::osha1stream
|
||||
class OSHA1streamAllocator
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
typedef osha1stream stream_type;
|
||||
|
||||
//- The output stream
|
||||
stream_type stream_;
|
||||
Foam::osha1stream stream_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
OSHA1streamAllocator() = default;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Full access to the sha1
|
||||
SHA1& sha1() noexcept
|
||||
{
|
||||
return stream_.sha1();
|
||||
}
|
||||
|
||||
|
||||
//- Return SHA1::Digest for the data processed until now
|
||||
SHA1Digest digest()
|
||||
{
|
||||
return stream_.sha1().digest();
|
||||
}
|
||||
|
||||
|
||||
//- Clear the SHA1 calculation
|
||||
void reset()
|
||||
{
|
||||
return stream_.sha1().clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
@ -188,16 +153,15 @@ class OSHA1stream
|
||||
{
|
||||
typedef Detail::OSHA1streamAllocator allocator_type;
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No copy construct
|
||||
OSHA1stream(const OSHA1stream&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const OSHA1stream&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
//- No copy construct
|
||||
OSHA1stream(const OSHA1stream&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const OSHA1stream&) = delete;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct with an empty digest
|
||||
@ -211,6 +175,18 @@ public:
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Full access to the sha1
|
||||
SHA1& sha1() noexcept { return stream_.sha1(); }
|
||||
|
||||
//- Return SHA1::Digest for the data processed until now
|
||||
SHA1Digest digest() { return stream_.digest(); }
|
||||
|
||||
//- Clear the SHA1 calculation
|
||||
void reset() { stream_.reset(); }
|
||||
|
||||
|
||||
// Write Functions
|
||||
|
||||
//- Add (unquoted) string contents.
|
||||
@ -227,7 +203,7 @@ public:
|
||||
// \deprecated(2017-07) - use reset() method
|
||||
void rewind()
|
||||
{
|
||||
sha1().clear();
|
||||
stream_.sha1().clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
352
src/OpenFOAM/db/IOstreams/memory/ICharStream.H
Normal file
352
src/OpenFOAM/db/IOstreams/memory/ICharStream.H
Normal file
@ -0,0 +1,352 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2023 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/>.
|
||||
|
||||
Class
|
||||
Foam::ICharStream
|
||||
|
||||
Description
|
||||
An input stream that reads from a List and manages the List storage.
|
||||
Similar to IStringStream but with a List for its storage instead of
|
||||
as string to allow reuse of List contents without copying.
|
||||
|
||||
See Also
|
||||
Foam::OCharStream
|
||||
Foam::ISpanStream
|
||||
Foam::OSpanStream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_ICharStream_H
|
||||
#define Foam_ICharStream_H
|
||||
|
||||
#include "ISpanStream.H"
|
||||
#include "List.H"
|
||||
#include "DynamicList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class icharstream;
|
||||
class ICharStream;
|
||||
|
||||
// Older names (prior to 2023-08)
|
||||
typedef ICharStream IListStream;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class icharstream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- Similar to std::istringstream, but with the ability to swap
|
||||
//- character content.
|
||||
//- Has some similarity to std::ispanstream (C++23)
|
||||
class icharstream
|
||||
:
|
||||
virtual public std::ios,
|
||||
protected Foam::memorybuf::in_dynamic,
|
||||
public std::istream
|
||||
{
|
||||
typedef Foam::memorybuf::in_dynamic buffer_type;
|
||||
typedef std::istream stream_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct - empty
|
||||
icharstream()
|
||||
:
|
||||
buffer_type(),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
//- Copy construct from content
|
||||
icharstream(const char* buffer, size_t nbytes)
|
||||
:
|
||||
icharstream()
|
||||
{
|
||||
reset(buffer, nbytes);
|
||||
}
|
||||
|
||||
// //- Construct (deep copy) from span character content
|
||||
// explicit icharstream(stdFoam::span<char> s)
|
||||
// :
|
||||
// icharstream()
|
||||
// {
|
||||
// reset(buffer, nbytes);
|
||||
// }
|
||||
|
||||
//- Move construct from List
|
||||
icharstream(List<char>&& buffer)
|
||||
:
|
||||
icharstream()
|
||||
{
|
||||
swap(buffer);
|
||||
}
|
||||
|
||||
//- Move construct from DynamicList
|
||||
template<int SizeMin>
|
||||
icharstream(DynamicList<char,SizeMin>&& buffer)
|
||||
:
|
||||
icharstream()
|
||||
{
|
||||
swap(buffer);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The current get position within the buffer (tellg)
|
||||
std::streampos input_pos() const
|
||||
{
|
||||
return buffer_type::span_tellg();
|
||||
}
|
||||
|
||||
//- The get buffer capacity
|
||||
std::streamsize capacity() const
|
||||
{
|
||||
return buffer_type::span_capacity();
|
||||
}
|
||||
|
||||
//- The number of characters remaining in the get area.
|
||||
//- Same as (capacity() - input_pos())
|
||||
std::streamsize remaining() const
|
||||
{
|
||||
return buffer_type::span_remaining();
|
||||
}
|
||||
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return buffer_type::span_list();
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
void rewind()
|
||||
{
|
||||
buffer_type::pubseekpos(0, std::ios_base::in);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Reset content (copy)
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
{
|
||||
buffer_type::reset(buffer, nbytes);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
buffer_type::swap(other);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
buffer_type::swap(other);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Some information about the input buffer position/capacity
|
||||
void debug_info(Ostream& os) const
|
||||
{
|
||||
os << "get="
|
||||
<< input_pos() << '/' << capacity();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Detail::ICharStreamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An allocator for holding Foam::icharstream
|
||||
class ICharStreamAllocator
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The stream
|
||||
Foam::icharstream stream_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
ICharStreamAllocator() = default;
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ICharStream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An ISstream with internal List storage. Always UNCOMPRESSED.
|
||||
class ICharStream
|
||||
:
|
||||
public Detail::ICharStreamAllocator,
|
||||
public Foam::ISstream
|
||||
{
|
||||
typedef Detail::ICharStreamAllocator allocator_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct (empty), optionally with specified stream option
|
||||
explicit ICharStream
|
||||
(
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(),
|
||||
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Copy construct from string content
|
||||
explicit ICharStream
|
||||
(
|
||||
const std::string& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ICharStream(streamOpt)
|
||||
{
|
||||
stream_.reset(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
//- Move construct from List
|
||||
explicit ICharStream
|
||||
(
|
||||
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ICharStream(streamOpt)
|
||||
{
|
||||
stream_.swap(buffer);
|
||||
}
|
||||
|
||||
//- Move construct from DynamicList (uses current size)
|
||||
template<int SizeMin>
|
||||
explicit ICharStream
|
||||
(
|
||||
DynamicList<char,SizeMin>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ICharStream(streamOpt)
|
||||
{
|
||||
stream_.swap(buffer);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Position of the get buffer
|
||||
std::streampos tellg() const { return stream_.input_pos(); }
|
||||
|
||||
//- The current get position within the buffer (tellg)
|
||||
std::streampos input_pos() const { return stream_.input_pos(); }
|
||||
|
||||
//- The input list size. Same as capacity()
|
||||
label size() const { return label(stream_.capacity()); }
|
||||
|
||||
//- The get buffer capacity
|
||||
std::streamsize capacity() const { return stream_.capacity(); }
|
||||
|
||||
//- The number of characters remaining in the get area.
|
||||
//- Same as (capacity() - input_pos())
|
||||
std::streamsize remaining() const { return stream_.remaining(); }
|
||||
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> list() const { return stream_.list(); }
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
stream_.rewind();
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Reset content (copy)
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
{
|
||||
stream_.reset(buffer, nbytes);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
stream_.swap(other);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
stream_.swap(other);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- A non-const reference to const Istream
|
||||
// Needed for read-constructors where the stream argument is temporary
|
||||
Istream& operator()() const
|
||||
{
|
||||
// Could also rewind
|
||||
return const_cast<ICharStream&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,261 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2022 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/>.
|
||||
|
||||
Class
|
||||
Foam::IListStream
|
||||
|
||||
Description
|
||||
An input stream that reads from a List and manages the List storage.
|
||||
Similar to IStringStream but with a List for its storage instead of
|
||||
as string to allow reuse of List contents without copying.
|
||||
|
||||
See Also
|
||||
Foam::OListStream
|
||||
Foam::UIListStream
|
||||
Foam::UOListStream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_IListStream_H
|
||||
#define Foam_IListStream_H
|
||||
|
||||
#include "List.H"
|
||||
#include "UIListStream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Detail::IListStreamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An stream/stream-buffer input allocator with List storage
|
||||
class IListStreamAllocator
|
||||
:
|
||||
private List<char>,
|
||||
public UIListStreamAllocator
|
||||
{
|
||||
protected:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
IListStreamAllocator()
|
||||
:
|
||||
List<char>(),
|
||||
UIListStreamAllocator(List<char>::data(), List<char>::size())
|
||||
{}
|
||||
|
||||
//- Move construct from List
|
||||
IListStreamAllocator(List<char>&& buffer)
|
||||
:
|
||||
List<char>(std::move(buffer)),
|
||||
UIListStreamAllocator(List<char>::data(), List<char>::size())
|
||||
{}
|
||||
|
||||
//- Move construct from DynamicList
|
||||
template<int SizeMin>
|
||||
IListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
|
||||
:
|
||||
List<char>(std::move(buffer)),
|
||||
UIListStreamAllocator(List<char>::data(), List<char>::size())
|
||||
{}
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Convenience method to address the underlying List storage
|
||||
inline void reset_gbuffer()
|
||||
{
|
||||
UIListStreamAllocator::reset
|
||||
(
|
||||
List<char>::data(),
|
||||
List<char>::size()
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The current get position in the buffer
|
||||
using UIListStreamAllocator::size;
|
||||
|
||||
//- Clear storage
|
||||
inline void clearStorage()
|
||||
{
|
||||
List<char>::clear();
|
||||
reset_gbuffer();
|
||||
}
|
||||
|
||||
//- Transfer contents to other List
|
||||
inline void swap(List<char>& list)
|
||||
{
|
||||
List<char>::swap(list);
|
||||
reset_gbuffer();
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class IListStream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An ISstream with internal List storage. Always UNCOMPRESSED.
|
||||
class IListStream
|
||||
:
|
||||
public Detail::IListStreamAllocator,
|
||||
public ISstream
|
||||
{
|
||||
typedef Detail::IListStreamAllocator allocator_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct with an empty list
|
||||
explicit IListStream
|
||||
(
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(),
|
||||
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Move construct from List
|
||||
explicit IListStream
|
||||
(
|
||||
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(std::move(buffer)),
|
||||
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
|
||||
//- Move construct from DynamicList
|
||||
template<int SizeMin>
|
||||
explicit IListStream
|
||||
(
|
||||
DynamicList<char,SizeMin>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(std::move(buffer)),
|
||||
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The current get position in the buffer
|
||||
using allocator_type::size;
|
||||
|
||||
|
||||
//- Return the current get position in the buffer
|
||||
std::streampos pos() const
|
||||
{
|
||||
return allocator_type::tellg();
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
allocator_type::rewind();
|
||||
setGood(); // resynchronize with internal state
|
||||
}
|
||||
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- A non-const reference to const Istream
|
||||
// Needed for read-constructors where the stream argument is temporary
|
||||
Istream& operator()() const
|
||||
{
|
||||
// Could also rewind
|
||||
return const_cast<IListStream&>(*this);
|
||||
}
|
||||
|
||||
|
||||
// Additional constructors and methods (as per v2012 and earlier)
|
||||
#ifdef Foam_IOstream_extras
|
||||
|
||||
//- Construct with an empty list
|
||||
explicit IListStream
|
||||
(
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
IListStream(IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
|
||||
//- Move construct from List
|
||||
IListStream
|
||||
(
|
||||
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
IListStream(std::move(buffer), IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
|
||||
//- Move construct from DynamicList
|
||||
template<int SizeMin>
|
||||
explicit IListStream
|
||||
(
|
||||
DynamicList<char,SizeMin>&& buffer,
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
IListStream(std::move(buffer), IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
#endif /* Foam_IOstream_extras */
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
352
src/OpenFOAM/db/IOstreams/memory/ISpanStream.H
Normal file
352
src/OpenFOAM/db/IOstreams/memory/ISpanStream.H
Normal file
@ -0,0 +1,352 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2023 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/>.
|
||||
|
||||
Class
|
||||
Foam::ISpanStream
|
||||
|
||||
Description
|
||||
Similar to IStringStream but using an externally managed buffer for its
|
||||
input. This allows the input buffer to be filled (and refilled) from
|
||||
various sources.
|
||||
|
||||
Note that this stream will normally be used as a "one-shot" reader.
|
||||
Caution must be exercised that the referenced buffer remains valid and
|
||||
without any intermediate resizing for the duration of the stream's use.
|
||||
|
||||
An example of possible use:
|
||||
\code
|
||||
DynamicList<char> buffer(4096); // allocate some large buffer
|
||||
|
||||
nread = something.read(buffer.data(),1024); // fill with content
|
||||
buffer.resize(nread); // content size
|
||||
|
||||
// Construct dictionary, or something else
|
||||
ISpanStream is(buffer)
|
||||
dictionary dict1(is);
|
||||
|
||||
// Sometime later
|
||||
nread = something.read(buffer.data(),2048); // fill with content
|
||||
buffer.resize(nread); // content size
|
||||
|
||||
// Without intermediate variable
|
||||
dictionary dict2(ISpanStream(buffer)());
|
||||
\endcode
|
||||
|
||||
See Also
|
||||
Foam::ICharStream
|
||||
Foam::OCharStream
|
||||
Foam::OSpanStream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_ISpanStream_H
|
||||
#define Foam_ISpanStream_H
|
||||
|
||||
#include "UList.H"
|
||||
#include "ISstream.H"
|
||||
#include "memoryStreamBuffer.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class ispanstream;
|
||||
class ISpanStream;
|
||||
|
||||
// Older names (prior to 2023-08)
|
||||
typedef ispanstream uiliststream;
|
||||
typedef ISpanStream UIListStream;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ispanstream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- Similar to std::istringstream, but with an externally managed input buffer
|
||||
//- which makes it most similar to std::ispanstream (C++23)
|
||||
// This allows the input buffer to be filled or refilled from various sources
|
||||
// without copying.
|
||||
class ispanstream
|
||||
:
|
||||
virtual public std::ios,
|
||||
protected Foam::memorybuf::in_base,
|
||||
public std::istream
|
||||
{
|
||||
typedef Foam::memorybuf::in_base buffer_type;
|
||||
typedef std::istream stream_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct - empty
|
||||
ispanstream()
|
||||
:
|
||||
buffer_type(),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
//- Construct (shallow copy) for character array and number of bytes
|
||||
ispanstream(const char* buffer, size_t nbytes)
|
||||
:
|
||||
buffer_type(const_cast<char*>(buffer), nbytes),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
// //- Construct (shallow copy) from span character content
|
||||
// ispanstream(stdFoam::span<char> s)
|
||||
// :
|
||||
// buffer_type(const_cast<char*>(s.data()), s.size()),
|
||||
// stream_type(static_cast<buffer_type*>(this))
|
||||
// {}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The current get position within the buffer (tellg)
|
||||
std::streampos input_pos() const
|
||||
{
|
||||
return buffer_type::span_tellg();
|
||||
}
|
||||
|
||||
//- The get buffer capacity
|
||||
std::streamsize capacity() const
|
||||
{
|
||||
return buffer_type::span_capacity();
|
||||
}
|
||||
|
||||
//- The number of characters remaining in the get area.
|
||||
//- Same as (capacity() - input_pos())
|
||||
std::streamsize remaining() const
|
||||
{
|
||||
return buffer_type::span_remaining();
|
||||
}
|
||||
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return buffer_type::span_list();
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
void rewind()
|
||||
{
|
||||
buffer_type::pubseekpos(0, std::ios_base::in);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Reset the get buffer area
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
{
|
||||
buffer_type::resetg(const_cast<char*>(buffer), nbytes);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Reset the get buffer area to use the data from a string
|
||||
void reset(const std::string& s)
|
||||
{
|
||||
buffer_type::resetg(const_cast<char*>(&s[0]), s.size());
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Some information about the input buffer position/capacity
|
||||
void debug_info(Ostream& os) const
|
||||
{
|
||||
os << "get="
|
||||
<< input_pos() << '/' << capacity();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Detail::ISpanStreamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An allocator for holding Foam::ispanstream
|
||||
class ISpanStreamAllocator
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The stream
|
||||
Foam::ispanstream stream_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct (empty)
|
||||
ISpanStreamAllocator() = default;
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ISpanStream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class ISpanStream
|
||||
:
|
||||
public Detail::ISpanStreamAllocator,
|
||||
public Foam::ISstream
|
||||
{
|
||||
typedef Detail::ISpanStreamAllocator allocator_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct (empty), optionally with specified stream option
|
||||
explicit ISpanStream
|
||||
(
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(),
|
||||
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Construct using specified buffer and number of bytes
|
||||
ISpanStream
|
||||
(
|
||||
const char* buffer,
|
||||
size_t nbytes,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(streamOpt)
|
||||
{
|
||||
reset(buffer, nbytes);
|
||||
}
|
||||
|
||||
//- Use data area from string content
|
||||
explicit ISpanStream
|
||||
(
|
||||
const std::string& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(streamOpt)
|
||||
{
|
||||
reset(buffer);
|
||||
}
|
||||
|
||||
//- Construct using data area from a List and number of bytes
|
||||
ISpanStream
|
||||
(
|
||||
const ::Foam::UList<char>& buffer,
|
||||
size_t nbytes,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(buffer.cdata(), nbytes, streamOpt)
|
||||
{}
|
||||
|
||||
//- Construct using data area from a List and its inherent storage size
|
||||
// Uses addressed size, thus no special treatment for a DynamicList
|
||||
explicit ISpanStream
|
||||
(
|
||||
const ::Foam::UList<char>& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(buffer.cdata(), buffer.size(), streamOpt)
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Position of the get buffer
|
||||
std::streampos tellg() const { return stream_.input_pos(); }
|
||||
|
||||
//- The current get position within the buffer (tellg)
|
||||
std::streampos input_pos() const { return stream_.input_pos(); }
|
||||
|
||||
//- The input list size. Same as capacity()
|
||||
label size() const { return label(stream_.capacity()); }
|
||||
|
||||
//- The get buffer capacity
|
||||
std::streamsize capacity() const { return stream_.capacity(); }
|
||||
|
||||
//- The number of characters remaining in the get area.
|
||||
//- Same as (capacity() - input_pos())
|
||||
std::streamsize remaining() const { return stream_.remaining(); }
|
||||
|
||||
|
||||
//- Span of the current input characters (is modifiable!)
|
||||
UList<char> list() const { return stream_.list(); }
|
||||
|
||||
//- Reset input area, position to buffer start and clear errors
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
{
|
||||
stream_.reset(buffer, nbytes);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Reset input area to use data from a string
|
||||
void reset(const std::string& s)
|
||||
{
|
||||
stream_.reset(s);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
stream_.rewind();
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- A non-const reference to const Istream
|
||||
// Needed for read-constructors where the stream argument is temporary
|
||||
Istream& operator()() const
|
||||
{
|
||||
// Could also rewind
|
||||
return const_cast<ISpanStream&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
316
src/OpenFOAM/db/IOstreams/memory/OCharStream.H
Normal file
316
src/OpenFOAM/db/IOstreams/memory/OCharStream.H
Normal file
@ -0,0 +1,316 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2023 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/>.
|
||||
|
||||
Class
|
||||
Foam::OCharStream
|
||||
|
||||
Description
|
||||
An output stream that writes to a List and manages the List storage.
|
||||
Similar to OStringStream but with a List for its storage instead of
|
||||
as string to allow reuse of List contents without copying.
|
||||
|
||||
The default initial size is 512-bytes and uses size doubling.
|
||||
After construction can use the reserve() method to adjust this.
|
||||
|
||||
See Also
|
||||
Foam::ICharStream
|
||||
Foam::OSpanStream
|
||||
Foam::ISpanStream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_OCharStream_H
|
||||
#define Foam_OCharStream_H
|
||||
|
||||
#include "OSpanStream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class ocharstream;
|
||||
class OCharStream;
|
||||
|
||||
// Older names (prior to 2023-08)
|
||||
typedef OCharStream OListStream;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ocharstream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- Similar to std::ostringstream, but with the ability to swap
|
||||
//- character content.
|
||||
//- Has some similarity to std::ospanstream (C++23)
|
||||
class ocharstream
|
||||
:
|
||||
virtual public std::ios,
|
||||
protected Foam::memorybuf::out_dynamic,
|
||||
public std::ostream
|
||||
{
|
||||
typedef Foam::memorybuf::out_dynamic buffer_type;
|
||||
typedef std::ostream stream_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct - empty
|
||||
ocharstream()
|
||||
:
|
||||
buffer_type(),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
//- Move construct from List
|
||||
ocharstream(List<char>&& buffer)
|
||||
:
|
||||
ocharstream()
|
||||
{
|
||||
swap(buffer);
|
||||
}
|
||||
|
||||
//- Move construct from DynamicList
|
||||
template<int SizeMin>
|
||||
ocharstream(DynamicList<char,SizeMin>&& buffer)
|
||||
:
|
||||
ocharstream()
|
||||
{
|
||||
swap(buffer);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The current output position within the buffer (tellp)
|
||||
std::streampos output_pos() const
|
||||
{
|
||||
return (buffer_type::span_tellp());
|
||||
}
|
||||
|
||||
//- The put buffer capacity
|
||||
std::streamsize capacity() const
|
||||
{
|
||||
return buffer_type::span_capacity();
|
||||
}
|
||||
|
||||
//- Reserve output space for at least this amount
|
||||
void reserve(const std::streamsize n)
|
||||
{
|
||||
buffer_type::reserve(n);
|
||||
}
|
||||
|
||||
//- Span of the current output characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return buffer_type::span_list();
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
void rewind()
|
||||
{
|
||||
buffer_type::pubseekpos(0, std::ios_base::out);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
buffer_type::swap(other);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
buffer_type::swap(other);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Some information about the output buffer position/capacity
|
||||
void debug_info(Ostream& os) const
|
||||
{
|
||||
os << "put="
|
||||
<< output_pos() << '/' << capacity();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Detail::OCharStreamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An allocator for holding Foam::ocharstream
|
||||
class OCharStreamAllocator
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The stream
|
||||
Foam::ocharstream stream_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct - empty
|
||||
OCharStreamAllocator() = default;
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class OCharStream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An OSstream with internal List storage
|
||||
class OCharStream
|
||||
:
|
||||
public Detail::OCharStreamAllocator,
|
||||
public Foam::OSstream
|
||||
{
|
||||
typedef Detail::OCharStreamAllocator allocator_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct (empty output)
|
||||
explicit OCharStream
|
||||
(
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(),
|
||||
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Construct with initial reserved number of bytes
|
||||
explicit OCharStream
|
||||
(
|
||||
size_t nbytes,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
OCharStream(streamOpt)
|
||||
{
|
||||
stream_.reserve(nbytes);
|
||||
}
|
||||
|
||||
//- Move construct from a List
|
||||
explicit OCharStream
|
||||
(
|
||||
::Foam::List<char>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
OCharStream(streamOpt)
|
||||
{
|
||||
stream_.swap(buffer);
|
||||
}
|
||||
|
||||
//- Move construct from a DynamicList (uses entire capacity)
|
||||
template<int SizeMin>
|
||||
explicit OCharStream
|
||||
(
|
||||
::Foam::DynamicList<char,SizeMin>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
OCharStream(streamOpt)
|
||||
{
|
||||
stream_.swap(buffer);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Position of the put buffer
|
||||
std::streampos tellp() const { return stream_.output_pos(); }
|
||||
|
||||
//- The current output position within the buffer (tellp)
|
||||
std::streampos output_pos() const { return stream_.output_pos(); }
|
||||
|
||||
//- The current output size. Same as tellp(), output_pos()
|
||||
label size() const { return label(stream_.output_pos()); }
|
||||
|
||||
//- The put buffer capacity
|
||||
std::streamsize capacity() const { return stream_.capacity(); }
|
||||
|
||||
//- Reserve output space for at least this amount
|
||||
void reserve(const std::streamsize n) { stream_.reserve(n); }
|
||||
|
||||
//- Span of the current output characters (is modifiable!)
|
||||
UList<char> list() const { return stream_.list(); }
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
stream_.rewind();
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
stream_.swap(other);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
stream_.swap(other);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const;
|
||||
|
||||
|
||||
// Houskeeping
|
||||
|
||||
//- Block size was used in OpenFOAM-v2306 and earlier
|
||||
void setBlockSize(int n) {}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,103 +42,6 @@ Description
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class countstreambuf Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- A streambuf class for determining byte counts
|
||||
class countstreambuf
|
||||
:
|
||||
public std::streambuf
|
||||
{
|
||||
//- The number of bytes counted
|
||||
std::streamsize size_;
|
||||
|
||||
protected:
|
||||
|
||||
//- Set position pointer to relative position
|
||||
virtual std::streampos seekoff
|
||||
(
|
||||
std::streamoff off,
|
||||
std::ios_base::seekdir way,
|
||||
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
|
||||
)
|
||||
{
|
||||
if (which & std::ios_base::out)
|
||||
{
|
||||
if (way == std::ios_base::beg)
|
||||
{
|
||||
size_ = off;
|
||||
}
|
||||
else if (way == std::ios_base::cur)
|
||||
{
|
||||
size_ += off;
|
||||
}
|
||||
else if (way == std::ios_base::end)
|
||||
{
|
||||
// not really possible
|
||||
}
|
||||
|
||||
return size_; // tellp()
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//- Set position pointer to absolute position
|
||||
// For the counter, adjust the count accordingly.
|
||||
virtual std::streampos seekpos
|
||||
(
|
||||
std::streampos pos,
|
||||
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
|
||||
)
|
||||
{
|
||||
return seekoff(pos, std::ios_base::beg, which);
|
||||
}
|
||||
|
||||
|
||||
//- Handle output counting via overflow
|
||||
virtual int overflow(int c = EOF)
|
||||
{
|
||||
if (c != EOF)
|
||||
{
|
||||
++size_;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//- Put sequence of characters
|
||||
virtual std::streamsize xsputn(const char* s, std::streamsize n)
|
||||
{
|
||||
size_ += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Default construct, or with precount size
|
||||
explicit countstreambuf(std::streamsize precount=0)
|
||||
:
|
||||
size_(precount)
|
||||
{}
|
||||
|
||||
//- \return The buffer put position == number of bytes counted.
|
||||
std::streamsize tellp() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
//- Some information about the number of bytes counted
|
||||
void printBufInfo(Ostream& os) const
|
||||
{
|
||||
os << "count=" << size_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ocountstream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -149,34 +52,124 @@ public:
|
||||
class ocountstream
|
||||
:
|
||||
virtual public std::ios,
|
||||
protected countstreambuf,
|
||||
public std::ostream
|
||||
{
|
||||
//- A streambuf class for determining byte counts
|
||||
class countbuf : public std::streambuf
|
||||
{
|
||||
//- The number of bytes counted
|
||||
std::streamsize size_;
|
||||
|
||||
protected:
|
||||
|
||||
//- Set position pointer to relative position
|
||||
virtual std::streampos seekoff
|
||||
(
|
||||
std::streamoff off,
|
||||
std::ios_base::seekdir way,
|
||||
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
|
||||
)
|
||||
{
|
||||
if (which & std::ios_base::out)
|
||||
{
|
||||
if (way == std::ios_base::beg)
|
||||
{
|
||||
size_ = off;
|
||||
}
|
||||
else if (way == std::ios_base::cur)
|
||||
{
|
||||
size_ += off;
|
||||
}
|
||||
else if (way == std::ios_base::end)
|
||||
{
|
||||
// not really possible
|
||||
}
|
||||
|
||||
return size_; // Like span_tellp()
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//- Set position pointer to absolute position
|
||||
// For the counter, adjust the count accordingly.
|
||||
virtual std::streampos seekpos
|
||||
(
|
||||
std::streampos pos,
|
||||
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
|
||||
)
|
||||
{
|
||||
return seekoff(pos, std::ios_base::beg, which);
|
||||
}
|
||||
|
||||
//- Output overflow handling - increment counter
|
||||
virtual int overflow(int_type c = traits_type::eof())
|
||||
{
|
||||
if (c != traits_type::eof()) ++size_;
|
||||
return c;
|
||||
}
|
||||
|
||||
//- Put sequence of characters - increment counter
|
||||
virtual std::streamsize xsputn(const char* s, std::streamsize n)
|
||||
{
|
||||
size_ += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct, count = 0
|
||||
countbuf() : size_(0) {}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The number of bytes counted.
|
||||
std::streamsize count() const noexcept { return size_; }
|
||||
|
||||
//- Reset the count
|
||||
void reset(std::streamsize n = 0) noexcept { size_ = n; }
|
||||
};
|
||||
|
||||
|
||||
// Private Data
|
||||
|
||||
typedef countbuf buffer_type;
|
||||
typedef std::ostream stream_type;
|
||||
|
||||
//- Reference to the underlying buffer
|
||||
buffer_type buf_;
|
||||
|
||||
public:
|
||||
|
||||
//- Default construct
|
||||
ocountstream()
|
||||
:
|
||||
countstreambuf(),
|
||||
std::ostream(static_cast<countstreambuf*>(this))
|
||||
{}
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
ocountstream() : stream_type(&buf_) {}
|
||||
|
||||
|
||||
//- \return The buffer put position == number of bytes counted.
|
||||
using countstreambuf::tellp;
|
||||
// Member Functions
|
||||
|
||||
//- \return The number of bytes counted
|
||||
std::streamsize size() const
|
||||
{
|
||||
return countstreambuf::tellp();
|
||||
}
|
||||
//- This hides both signatures of std::basic_ios::rdbuf()
|
||||
countbuf* rdbuf() { return &buf_; }
|
||||
|
||||
//- Rewind the stream, reset the count
|
||||
void rewind()
|
||||
{
|
||||
this->pubseekpos(0, std::ios_base::out);
|
||||
clear(); // for safety, clear any old errors
|
||||
}
|
||||
//- \return The number of bytes counted
|
||||
std::streamsize count() const noexcept { return buf_.count(); }
|
||||
|
||||
//- Reset the count
|
||||
void reset(std::streamsize n = 0) noexcept
|
||||
{
|
||||
buf_.reset(n);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Some information about the output buffer position/capacity
|
||||
void debug_info(Ostream& os) const
|
||||
{
|
||||
os << "count=" << buf_.count();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -187,55 +180,21 @@ namespace Detail
|
||||
Class Detail::OCountStreamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An stream/stream-buffer allocator for counting
|
||||
//- An allocator for holding Foam::ocountstream
|
||||
class OCountStreamAllocator
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
typedef std::ostream stream_type;
|
||||
|
||||
//- The stream buffer
|
||||
countstreambuf buf_;
|
||||
|
||||
//- The output stream
|
||||
stream_type stream_;
|
||||
Foam::ocountstream stream_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct, or with precount size
|
||||
OCountStreamAllocator(std::streamsize precount=0)
|
||||
:
|
||||
buf_(precount),
|
||||
stream_(&buf_)
|
||||
{}
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
void printBufInfo(Ostream& os) const
|
||||
{
|
||||
buf_.printBufInfo(os);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- The number of bytes counted
|
||||
std::streamsize size() const
|
||||
{
|
||||
return buf_.tellp();
|
||||
}
|
||||
|
||||
//- Rewind the stream, reset the count
|
||||
void rewind()
|
||||
{
|
||||
buf_.pubseekpos(0);
|
||||
stream_.clear(); // for safety, clear any old errors
|
||||
}
|
||||
//- Default construct
|
||||
OCountStreamAllocator() = default;
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
@ -270,35 +229,33 @@ public:
|
||||
//- Copy construct
|
||||
OCountStream(const OCountStream& str)
|
||||
:
|
||||
allocator_type(str.size()),
|
||||
allocator_type(),
|
||||
OSstream(stream_, str.name(), static_cast<IOstreamOption>(str))
|
||||
{}
|
||||
{
|
||||
stream_.reset(str.count());
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- \return The number of bytes counted
|
||||
std::streamsize count() const noexcept { return stream_.count(); }
|
||||
|
||||
//- \return The number of bytes counted
|
||||
std::streamsize size() const noexcept { return stream_.count(); }
|
||||
|
||||
//- Reset the count
|
||||
void reset(std::streamsize n = 0) noexcept { stream_.reset(n); }
|
||||
|
||||
//- Rewind the stream, reset the count, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
allocator_type::rewind();
|
||||
setGood(); // resynchronize with internal state
|
||||
stream_.reset();
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const;
|
||||
|
||||
|
||||
// Additional constructors and methods (as per v2012 and earlier)
|
||||
#ifdef Foam_IOstream_extras
|
||||
|
||||
//- Construct empty with format
|
||||
explicit OCountStream(IOstreamOption::streamFormat fmt)
|
||||
:
|
||||
OCountStream(IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
|
||||
#endif /* Foam_IOstream_extras */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -1,522 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2022 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/>.
|
||||
|
||||
Class
|
||||
Foam::OListStream
|
||||
|
||||
Description
|
||||
An output stream that writes to a List and manages the List storage.
|
||||
Similar to OStringStream but with a List for its storage instead of
|
||||
as string to allow reuse of List contents without copying.
|
||||
|
||||
The default list size is 512-bytes with a 256-byte block increment.
|
||||
These values can be changed after construction using the reserve() and
|
||||
the setBlockSize() methods.
|
||||
|
||||
See Also
|
||||
Foam::IListStream
|
||||
Foam::UOListStream
|
||||
Foam::UIListStream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_OListStream_H
|
||||
#define Foam_OListStream_H
|
||||
|
||||
#include "DynamicList.H"
|
||||
#include "OSstream.H"
|
||||
#include "memoryStreamBuffer.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Detail::OListStreamAllocator Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An stream/stream-buffer output allocator with DynamicList-like storage
|
||||
class OListStreamAllocator
|
||||
{
|
||||
//- A streambuf adapter with resizing similar to DynamicList
|
||||
class dynbuf
|
||||
:
|
||||
public memorybuf::out
|
||||
{
|
||||
friend class OListStreamAllocator;
|
||||
|
||||
//- Helper for block size - small list minimum of 64 bytes.
|
||||
constexpr static int min_size(int n)
|
||||
{
|
||||
return stdFoam::max(64, n);
|
||||
}
|
||||
|
||||
//- Block size when resizing the list
|
||||
int block_ = 256;
|
||||
|
||||
//- Underlying list storage.
|
||||
// Internally manage like a DynamicList, with its capacity known
|
||||
// from the list size and the addressable size known through the
|
||||
// stream pointers.
|
||||
List<char> storage_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
//- Increment capacity directly and adjust buffer pointers to
|
||||
//- correspond with the storage size.
|
||||
inline void minCapacity
|
||||
(
|
||||
const std::streamsize n,
|
||||
const std::streamsize cur = 0
|
||||
)
|
||||
{
|
||||
const auto newEnd = n + cur;
|
||||
if (newEnd > storage_.size())
|
||||
{
|
||||
auto newCapacity =
|
||||
(
|
||||
(storage_.size() + block_)
|
||||
- (storage_.size() % block_)
|
||||
);
|
||||
|
||||
while (newCapacity < newEnd)
|
||||
{
|
||||
newCapacity += block_;
|
||||
}
|
||||
|
||||
// Info<<"request:" << newEnd
|
||||
// << " cur cap:" << storage_.size()
|
||||
// << " new cap:" << newCapacity
|
||||
// << " pos:" << cur
|
||||
// << " incr:" << incr << endl;
|
||||
|
||||
storage_.resize(newCapacity);
|
||||
sync_pbuffer();
|
||||
pbump(cur);
|
||||
}
|
||||
}
|
||||
|
||||
//- Define new increment
|
||||
inline void setBlockSize(const int i)
|
||||
{
|
||||
const auto prev = block_;
|
||||
block_ = min_size(i);
|
||||
|
||||
if (block_ > prev)
|
||||
{
|
||||
minCapacity(0, tellp());
|
||||
}
|
||||
}
|
||||
|
||||
//- Handle overflow
|
||||
virtual int overflow(int c = EOF)
|
||||
{
|
||||
if (c != EOF)
|
||||
{
|
||||
// Need another output block
|
||||
minCapacity(block_, tellp());
|
||||
|
||||
*(pptr()) = c;
|
||||
pbump(1);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//- Put sequence of characters
|
||||
virtual std::streamsize xsputn(const char* s, std::streamsize n)
|
||||
{
|
||||
// Enough space so that appends work without problem
|
||||
minCapacity(n, tellp());
|
||||
|
||||
std::streamsize count = 0;
|
||||
while (count < n && pptr() < epptr())
|
||||
{
|
||||
*(pptr()) = *(s + count++);
|
||||
pbump(1);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//- Initialize put buffer
|
||||
void init_pbuffer(const std::streamsize n)
|
||||
{
|
||||
sync_pbuffer();
|
||||
minCapacity(n);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct, with initial reserved number of bytes
|
||||
dynbuf(size_t nbytes = 512)
|
||||
:
|
||||
storage_()
|
||||
{
|
||||
init_pbuffer(min_size(nbytes));
|
||||
}
|
||||
|
||||
//- Move construct from List
|
||||
dynbuf(List<char>&& buffer)
|
||||
:
|
||||
storage_(std::move(buffer))
|
||||
{
|
||||
init_pbuffer(block_);
|
||||
}
|
||||
|
||||
//- Move construct from DynamicList.
|
||||
template<int SizeMin>
|
||||
dynbuf(DynamicList<char,SizeMin>&& buffer)
|
||||
:
|
||||
storage_(std::move(buffer))
|
||||
{
|
||||
init_pbuffer(block_);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the current list output capacity
|
||||
inline label capacity() const
|
||||
{
|
||||
return storage_.size();
|
||||
}
|
||||
|
||||
//- Sync put buffer pointers to agree with list dimensions
|
||||
// Sets put pointer to the begin (rewind).
|
||||
inline void sync_pbuffer()
|
||||
{
|
||||
resetp(storage_.data(), storage_.size());
|
||||
}
|
||||
|
||||
//- Clear storage
|
||||
inline void clearStorage()
|
||||
{
|
||||
storage_.clear();
|
||||
sync_pbuffer();
|
||||
}
|
||||
|
||||
//- Shrink storage to addressed storage
|
||||
inline void shrink()
|
||||
{
|
||||
const auto cur = tellp(); // Addressed area
|
||||
|
||||
storage_.resize(cur);
|
||||
sync_pbuffer();
|
||||
pbump(cur);
|
||||
}
|
||||
|
||||
//- Transfer list contents to other List
|
||||
inline void swap(List<char>& other)
|
||||
{
|
||||
const auto cur = tellp(); // Addressed area
|
||||
|
||||
storage_.swap(other);
|
||||
storage_.resize(cur);
|
||||
sync_pbuffer();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList
|
||||
template<int SizeMin>
|
||||
inline void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
const auto cur = tellp(); // Addressed area
|
||||
|
||||
storage_.swap(other); // Swap full list
|
||||
other.setCapacity(other.size());
|
||||
other.resize(cur);
|
||||
sync_pbuffer();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
typedef std::ostream stream_type;
|
||||
|
||||
//- The stream buffer
|
||||
dynbuf buf_;
|
||||
|
||||
//- The stream
|
||||
stream_type stream_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct, with initial reserved number of bytes
|
||||
OListStreamAllocator(size_t nbytes = 512)
|
||||
:
|
||||
buf_(nbytes),
|
||||
stream_(&buf_)
|
||||
{}
|
||||
|
||||
//- Move construct from List
|
||||
OListStreamAllocator(List<char>&& buffer)
|
||||
:
|
||||
buf_(std::move(buffer)),
|
||||
stream_(&buf_)
|
||||
{}
|
||||
|
||||
//- Move construct from DynamicList
|
||||
template<int SizeMin>
|
||||
OListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
|
||||
:
|
||||
buf_(std::move(buffer)),
|
||||
stream_(&buf_)
|
||||
{}
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
void printBufInfo(Ostream& os) const
|
||||
{
|
||||
os << "put=" << buf_.tellp()
|
||||
<< "/" << buf_.capacity()
|
||||
<< " block=" << buf_.block_;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Const UList access to the characters written (shallow copy).
|
||||
inline const UList<char> list() const
|
||||
{
|
||||
return buf_.list();
|
||||
}
|
||||
|
||||
//- Non-const UList access to the characters written (shallow copy).
|
||||
inline UList<char> list()
|
||||
{
|
||||
return buf_.list();
|
||||
}
|
||||
|
||||
//- The current list output capacity
|
||||
inline label capacity() const
|
||||
{
|
||||
return buf_.capacity();
|
||||
}
|
||||
|
||||
//- The current output position in the buffer,
|
||||
//- which is also the addressed list size
|
||||
inline label size() const
|
||||
{
|
||||
return buf_.tellp();
|
||||
}
|
||||
|
||||
//- Reserve output space for at least this amount.
|
||||
inline void reserve(const std::streamsize n)
|
||||
{
|
||||
// Also maintain current position when resizing
|
||||
const auto cur = buf_.tellp();
|
||||
if (n > cur)
|
||||
{
|
||||
buf_.minCapacity(n - cur, cur);
|
||||
}
|
||||
}
|
||||
|
||||
//- Adjust block size for output
|
||||
inline void setBlockSize(int n)
|
||||
{
|
||||
return buf_.setBlockSize(n);
|
||||
}
|
||||
|
||||
//- Transfer list contents to other List
|
||||
inline void swap(List<char>& other)
|
||||
{
|
||||
buf_.swap(other);
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList
|
||||
template<int SizeMin>
|
||||
inline void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
buf_.swap(other);
|
||||
}
|
||||
|
||||
//- Shrink to addressed space, should not affect stream.
|
||||
inline void shrink()
|
||||
{
|
||||
buf_.shrink();
|
||||
}
|
||||
|
||||
//- Clear storage
|
||||
void clearStorage()
|
||||
{
|
||||
buf_.clearStorage();
|
||||
stream_.clear(); // for safety, clear any old errors
|
||||
}
|
||||
|
||||
//- Move to buffer start, clear errors
|
||||
void rewind()
|
||||
{
|
||||
buf_.pubseekpos(0, std::ios_base::out);
|
||||
stream_.clear(); // for safety, clear any old errors
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace Detail
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class OListStream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An OSstream attached to a List
|
||||
class OListStream
|
||||
:
|
||||
public Detail::OListStreamAllocator,
|
||||
public OSstream
|
||||
{
|
||||
typedef Detail::OListStreamAllocator allocator_type;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct (empty output)
|
||||
explicit OListStream
|
||||
(
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(),
|
||||
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Construct with initial reserved number of bytes
|
||||
explicit OListStream
|
||||
(
|
||||
size_t nbytes,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(nbytes),
|
||||
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Move construct from an existing List
|
||||
explicit OListStream
|
||||
(
|
||||
List<char>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(std::move(buffer)),
|
||||
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
//- Move construct from an existing DynamicList
|
||||
template<int SizeMin>
|
||||
explicit OListStream
|
||||
(
|
||||
DynamicList<char,SizeMin>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
allocator_type(std::move(buffer)),
|
||||
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
allocator_type::rewind();
|
||||
setGood(); // resynchronize with internal state
|
||||
}
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const;
|
||||
|
||||
|
||||
// Additional constructors and methods (as per v2012 and earlier)
|
||||
#ifdef Foam_IOstream_extras
|
||||
|
||||
//- Default construct (empty output)
|
||||
explicit OListStream
|
||||
(
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
OListStream(IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
//- Construct with initial reserved number of bytes
|
||||
explicit OListStream
|
||||
(
|
||||
size_t nbytes,
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
OListStream(nbytes, IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
//- Move construct from an existing List
|
||||
OListStream
|
||||
(
|
||||
List<char>&& buffer,
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
OListStream(std::move(buffer), IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
//- Move construct from an existing DynamicList
|
||||
template<int SizeMin>
|
||||
OListStream
|
||||
(
|
||||
DynamicList<char,SizeMin>&& buffer,
|
||||
IOstreamOption::streamFormat fmt
|
||||
)
|
||||
:
|
||||
OListStream(std::move(buffer), IOstreamOption(fmt))
|
||||
{}
|
||||
|
||||
#endif /* Foam_IOstream_extras */
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user