ENH: add OListStream::swap(DynamicList<char>&)

- 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<char> 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 >> ...
      }
This commit is contained in:
Mark Olesen
2019-07-31 11:31:40 +02:00
committed by Andrew Heather
parent b0d32ce1b4
commit 6f8da834a9
5 changed files with 59 additions and 23 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -147,7 +147,7 @@ int main(int argc, char *argv[])
// Create from other storage types // Create from other storage types
List<char> written; DynamicList<char> written;
Info<< nl; Info<< nl;
{ {
Info<<"create std::move(List)" << endl; Info<<"create std::move(List)" << endl;
@ -157,6 +157,11 @@ int main(int argc, char *argv[])
toString(Info, list) << endl; toString(Info, list) << endl;
OListStream buf1(std::move(list)); OListStream buf1(std::move(list));
Info<<"orig:";
toString(Info, list) << endl;
printInfo(buf1);
for (label i = 0; i < 26; ++i) for (label i = 0; i < 26; ++i)
{ {
buf1 << char('A' +i); buf1 << char('A' +i);
@ -179,6 +184,9 @@ int main(int argc, char *argv[])
Info<<"'captured' content "; Info<<"'captured' content ";
toString(Info, written); toString(Info, written);
Info<< nl
<< "content size=" << written.size()
<< " capacity=" << written.capacity() << nl;
Info<< "\nEnd\n" << endl; Info<< "\nEnd\n" << endl;

View File

@ -113,7 +113,7 @@ public:
reset_gbuffer(); reset_gbuffer();
} }
//- Transfer contents to other list //- Transfer contents to other List
inline void swap(List<char>& list) inline void swap(List<char>& list)
{ {
List<char>::swap(list); List<char>::swap(list);
@ -182,7 +182,7 @@ public:
{} {}
// Member functions // Member Functions
//- The current get position in the buffer //- The current get position in the buffer
using allocator_type::size; using allocator_type::size;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -45,7 +45,6 @@ See Also
#include "DynamicList.H" #include "DynamicList.H"
#include "OSstream.H" #include "OSstream.H"
#include "stdFoam.H"
#include "memoryStreamBuffer.H" #include "memoryStreamBuffer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -85,6 +84,7 @@ class OListStreamAllocator
// stream pointers. // stream pointers.
List<char> storage_; List<char> storage_;
protected: protected:
//- Increment capacity directly and adjust buffer pointers to //- Increment capacity directly and adjust buffer pointers to
@ -192,9 +192,9 @@ class OListStreamAllocator
init_pbuffer(block_); init_pbuffer(block_);
} }
//- Move construct from DynamicList //- Move construct from DynamicList.
template<int AnySize> template<int SizeMin>
dynbuf(DynamicList<char,AnySize>&& buffer) dynbuf(DynamicList<char,SizeMin>&& buffer)
: :
storage_(std::move(buffer)) storage_(std::move(buffer))
{ {
@ -211,6 +211,7 @@ class OListStreamAllocator
} }
//- Sync put buffer pointers to agree with list dimensions //- Sync put buffer pointers to agree with list dimensions
// Sets put pointer to the begin (rewind).
inline void sync_pbuffer() inline void sync_pbuffer()
{ {
resetp(storage_.data(), storage_.size()); resetp(storage_.data(), storage_.size());
@ -223,27 +224,43 @@ class OListStreamAllocator
sync_pbuffer(); sync_pbuffer();
} }
//- Shrink to addressed storage //- Shrink storage to addressed storage
inline void shrink() inline void shrink()
{ {
const auto cur = tellp(); const auto cur = tellp(); // Addressed area
storage_.resize(cur); storage_.resize(cur);
sync_pbuffer(); sync_pbuffer();
pbump(cur); pbump(cur);
} }
//- Transfer list contents to other list //- Transfer list contents to other List
inline void swap(List<char>& other) inline void swap(List<char>& other)
{ {
storage_.resize(tellp()); // Addressed area const auto cur = tellp(); // Addressed area
storage_.swap(other); 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(); sync_pbuffer();
} }
}; };
protected: protected:
// Protected data // Protected Data
typedef std::ostream stream_type; typedef std::ostream stream_type;
@ -334,12 +351,19 @@ public:
return buf_.setBlockSize(n); return buf_.setBlockSize(n);
} }
//- Transfer list contents to other list //- Transfer list contents to other List
inline void swap(List<char>& other) inline void swap(List<char>& other)
{ {
buf_.swap(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. //- Shrink to addressed space, should not affect stream.
inline void shrink() inline void shrink()
{ {

View File

@ -40,15 +40,15 @@ Description
nread = something.read(buffer.data(),1024); // fill with content nread = something.read(buffer.data(),1024); // fill with content
buffer.resize(nread); // content size buffer.resize(nread); // content size
// construct dictionary, or something else // Construct dictionary, or something else
UIListStream is(buffer) UIListStream is(buffer)
dictionary dict1(is); dictionary dict1(is);
// sometime later // Sometime later
nread = something.read(buffer.data(),2048); // fill with content nread = something.read(buffer.data(),2048); // fill with content
buffer.resize(nread); // content size buffer.resize(nread); // content size
// without intermediate variable // Without intermediate variable
dictionary dict2(UIListStream(buffer)()); dictionary dict2(UIListStream(buffer)());
\endcode \endcode

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -178,15 +178,17 @@ protected:
return count; return count;
} }
public: 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) in(char* s, std::streamsize n)
{ {
resetg(s, 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) inline void resetg(char* s, std::streamsize n)
{ {
if (s) if (s)
@ -256,15 +258,17 @@ protected:
return count; return count;
} }
public: 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) out(char* s, std::streamsize n)
{ {
resetp(s, 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) inline void resetp(char* s, std::streamsize n)
{ {
if (s) if (s)