From 6f8da834a902e100e3f15d44e18506469cd2cf02 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 31 Jul 2019 11:31:40 +0200 Subject: [PATCH] ENH: add OListStream::swap(DynamicList&) - allows full recovery of allocated space, not just addressable range. This can be particularly useful for code patterns that repeatedly reuse the same buffer space. For example, DynamicList buf(1024); // some loop { OListStream os(std::move(buf)); os << ... os.swap(buf); } Can read back from this buffer as a second operation: { UIListStream is(buf); is >> ... } --- .../test/OListStream/Test-OListStream.C | 12 ++++- .../db/IOstreams/memory/IListStream.H | 4 +- .../db/IOstreams/memory/OListStream.H | 46 ++++++++++++++----- .../db/IOstreams/memory/UIListStream.H | 6 +-- .../db/IOstreams/memory/memoryStreamBuffer.H | 14 ++++-- 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/applications/test/OListStream/Test-OListStream.C b/applications/test/OListStream/Test-OListStream.C index e5e52f2a9d..59047bf723 100644 --- a/applications/test/OListStream/Test-OListStream.C +++ b/applications/test/OListStream/Test-OListStream.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -147,7 +147,7 @@ int main(int argc, char *argv[]) // Create from other storage types - List written; + DynamicList written; Info<< nl; { Info<<"create std::move(List)" << endl; @@ -157,6 +157,11 @@ int main(int argc, char *argv[]) toString(Info, list) << endl; OListStream buf1(std::move(list)); + + Info<<"orig:"; + toString(Info, list) << endl; + printInfo(buf1); + for (label i = 0; i < 26; ++i) { buf1 << char('A' +i); @@ -179,6 +184,9 @@ int main(int argc, char *argv[]) Info<<"'captured' content "; toString(Info, written); + Info<< nl + << "content size=" << written.size() + << " capacity=" << written.capacity() << nl; Info<< "\nEnd\n" << endl; diff --git a/src/OpenFOAM/db/IOstreams/memory/IListStream.H b/src/OpenFOAM/db/IOstreams/memory/IListStream.H index 7170dc4300..dcebf657b9 100644 --- a/src/OpenFOAM/db/IOstreams/memory/IListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/IListStream.H @@ -113,7 +113,7 @@ public: reset_gbuffer(); } - //- Transfer contents to other list + //- Transfer contents to other List inline void swap(List& list) { List::swap(list); @@ -182,7 +182,7 @@ public: {} - // Member functions + // Member Functions //- The current get position in the buffer using allocator_type::size; diff --git a/src/OpenFOAM/db/IOstreams/memory/OListStream.H b/src/OpenFOAM/db/IOstreams/memory/OListStream.H index e95b0a91f0..6f73b78cc2 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OListStream.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -45,7 +45,6 @@ See Also #include "DynamicList.H" #include "OSstream.H" -#include "stdFoam.H" #include "memoryStreamBuffer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -85,6 +84,7 @@ class OListStreamAllocator // stream pointers. List storage_; + protected: //- Increment capacity directly and adjust buffer pointers to @@ -192,9 +192,9 @@ class OListStreamAllocator init_pbuffer(block_); } - //- Move construct from DynamicList - template - dynbuf(DynamicList&& buffer) + //- Move construct from DynamicList. + template + dynbuf(DynamicList&& buffer) : storage_(std::move(buffer)) { @@ -211,6 +211,7 @@ class OListStreamAllocator } //- 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()); @@ -223,27 +224,43 @@ class OListStreamAllocator sync_pbuffer(); } - //- Shrink to addressed storage + //- Shrink storage to addressed storage inline void shrink() { - const auto cur = tellp(); + const auto cur = tellp(); // Addressed area + storage_.resize(cur); sync_pbuffer(); pbump(cur); } - //- Transfer list contents to other list + //- Transfer list contents to other List inline void swap(List& other) { - storage_.resize(tellp()); // Addressed area + const auto cur = tellp(); // Addressed area + storage_.swap(other); + storage_.resize(cur); + sync_pbuffer(); + } + + //- Transfer list contents to a DynamicList + template + inline void swap(DynamicList& 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 + // Protected Data typedef std::ostream stream_type; @@ -334,12 +351,19 @@ public: return buf_.setBlockSize(n); } - //- Transfer list contents to other list + //- Transfer list contents to other List inline void swap(List& other) { buf_.swap(other); } + //- Transfer list contents to a DynamicList + template + inline void swap(DynamicList& other) + { + buf_.swap(other); + } + //- Shrink to addressed space, should not affect stream. inline void shrink() { diff --git a/src/OpenFOAM/db/IOstreams/memory/UIListStream.H b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H index 76a50b0f1e..fcd1d11081 100644 --- a/src/OpenFOAM/db/IOstreams/memory/UIListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H @@ -40,15 +40,15 @@ Description nread = something.read(buffer.data(),1024); // fill with content buffer.resize(nread); // content size - // construct dictionary, or something else + // Construct dictionary, or something else UIListStream is(buffer) dictionary dict1(is); - // sometime later + // Sometime later nread = something.read(buffer.data(),2048); // fill with content buffer.resize(nread); // content size - // without intermediate variable + // Without intermediate variable dictionary dict2(UIListStream(buffer)()); \endcode diff --git a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H index 0a3ef59356..dd4e7ede51 100644 --- a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H +++ b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -178,15 +178,17 @@ protected: return count; } + public: - //- Construct for character array and number of bytes + //- Construct for character array (can be nullptr) and number of bytes in(char* s, std::streamsize n) { resetg(s, n); } - //- Reset for character array and number of bytes + //- Reset for character array (can be nullptr) and number of bytes + // Sets get pointer to the begin. inline void resetg(char* s, std::streamsize n) { if (s) @@ -256,15 +258,17 @@ protected: return count; } + public: - //- Construct for character array and number of bytes + //- Construct for character array (can be nullptr) and number of bytes out(char* s, std::streamsize n) { resetp(s, n); } - //- Reset for character array and number of bytes + //- Reset for character array (can be nullptr) and number of bytes. + // Sets put pointer to the begin. inline void resetp(char* s, std::streamsize n) { if (s)