ENH: refine SpanStream and CharStream methods
- support std::string_view (c++17) or span view (older c++) of stream buffer contents. This simplifies formatting + reparsing. Example, OCharStream os; os << ...; ISpanStream is(os.view()); is >> ...; - additional release() method for ICharStream, OCharStream that returns the contents as a DynamicList<char> and resets the stream. - provide a str() method for API compatibility with older std::ostringstream etc.
This commit is contained in:
parent
1ddcad820f
commit
3693d61e6c
@ -37,12 +37,28 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
Ostream& printString(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
os << '"';
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
os << *first;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
char buf[4];
|
||||
os << list.size() << '(';
|
||||
for (const char c : list)
|
||||
os << label(last-first) << '(';
|
||||
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
const char c = *first;
|
||||
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
@ -67,16 +83,35 @@ Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
}
|
||||
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
Ostream& printView(Ostream& os, std::string_view s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, stdFoam::span<char> s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
for (const char c : list)
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
return printString(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +120,7 @@ void printInfo(const BufType& buf)
|
||||
{
|
||||
Info<< nl << "=========================" << endl;
|
||||
buf.print(Info);
|
||||
Info<< "addr: " << Foam::name(buf.list().cdata()) << nl;
|
||||
toString(Info, buf.list());
|
||||
Info<< nl << "=========================" << endl;
|
||||
}
|
||||
@ -136,14 +172,16 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "transfer contents to a List" << endl;
|
||||
|
||||
ICharStream ibuf;
|
||||
|
||||
// Reclaim data storage from OCharStream -> ICharStream
|
||||
{
|
||||
List<char> data;
|
||||
obuf.swap(data);
|
||||
ibuf.swap(data);
|
||||
}
|
||||
ICharStream ibuf(std::move(obuf));
|
||||
|
||||
// OLD
|
||||
// ICharStream ibuf;
|
||||
// {
|
||||
// List<char> data;
|
||||
// obuf.swap(data);
|
||||
// ibuf.swap(data);
|
||||
// }
|
||||
|
||||
Info<< nl;
|
||||
Info<< nl << "input string:";
|
||||
|
@ -37,12 +37,28 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
Ostream& printString(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
os << '"';
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
os << *first;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
char buf[4];
|
||||
os << list.size() << '(';
|
||||
for (const char c : list)
|
||||
os << label(last-first) << '(';
|
||||
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
const char c = *first;
|
||||
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
@ -67,16 +83,35 @@ Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
}
|
||||
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
Ostream& printView(Ostream& os, std::string_view s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, stdFoam::span<char> s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list);
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
for (const char c : list)
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
return printString(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +120,7 @@ void printInfo(const BufType& buf)
|
||||
{
|
||||
Info<< nl << "=========================" << endl;
|
||||
buf.print(Info);
|
||||
Info<< "addr: " << Foam::name(buf.list().cdata()) << nl;
|
||||
toString(Info, buf.list());
|
||||
Info<< nl << "=========================" << endl;
|
||||
}
|
||||
@ -152,11 +188,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
printInfo(obuf);
|
||||
|
||||
obuf.shrink();
|
||||
|
||||
Info<< "after shrink" << nl;
|
||||
printInfo(obuf);
|
||||
|
||||
// Add some more
|
||||
for (label i=10; i < 15; ++i)
|
||||
{
|
||||
@ -175,13 +206,16 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "transfer contents to a List or ICharStream" << nl;
|
||||
|
||||
ICharStream ibuf;
|
||||
// Reclaim data storage from OCharStream -> ICharStream
|
||||
{
|
||||
List<char> data;
|
||||
obuf.swap(data);
|
||||
ibuf.swap(data);
|
||||
}
|
||||
ICharStream ibuf(std::move(obuf));
|
||||
|
||||
// OLD
|
||||
// ICharStream ibuf;
|
||||
// {
|
||||
// List<char> data;
|
||||
// obuf.swap(data);
|
||||
// ibuf.swap(data);
|
||||
// }
|
||||
|
||||
Info<<"original:";
|
||||
printInfo(obuf);
|
||||
@ -253,6 +287,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "Compact" << nl;
|
||||
printInfo(os2);
|
||||
|
||||
Info<< "address: " << Foam::name(os2.list().cdata()) << nl;
|
||||
|
||||
List<char> chars(os2.release());
|
||||
Info<< "chars: " << chars.size() << nl;
|
||||
Info<< "address: " << Foam::name(chars.cdata()) << nl;
|
||||
Info<< "release" << nl;
|
||||
printInfo(os2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,12 +39,28 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
Ostream& printString(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
os << '"';
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
os << *first;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
char buf[4];
|
||||
os << list.size() << '(';
|
||||
for (const char c : list)
|
||||
os << label(last-first) << '(';
|
||||
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
const char c = *first;
|
||||
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
@ -69,29 +85,41 @@ Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
}
|
||||
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
Ostream& printView(Ostream& os, std::string_view s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, stdFoam::span<char> s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
for (const char c : list)
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
return printString(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const std::vector<char>& list)
|
||||
{
|
||||
os << '"';
|
||||
for (const char c : list)
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
return printString(os, list.data(), list.data() + list.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,6 +53,7 @@ namespace Foam
|
||||
// Forward Declarations
|
||||
class icharstream;
|
||||
class ICharStream;
|
||||
class OCharStream;
|
||||
|
||||
// Older names (prior to 2023-08)
|
||||
typedef ICharStream IListStream;
|
||||
@ -93,14 +94,6 @@ public:
|
||||
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)
|
||||
:
|
||||
@ -143,7 +136,28 @@ public:
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return buffer_type::span_list();
|
||||
return UList<char>
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
label(buffer_type::size_bytes())
|
||||
);
|
||||
}
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(buffer_type::view())
|
||||
{
|
||||
return buffer_type::view();
|
||||
}
|
||||
|
||||
//- For istringstream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
std::string str() const
|
||||
{
|
||||
return std::string
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
buffer_type::size_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
@ -153,21 +167,21 @@ public:
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Reset content (copy)
|
||||
//- Reset stream content (copy), reset positions
|
||||
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
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
buffer_type::swap(other);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
@ -175,11 +189,18 @@ public:
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Reset stream and return contents as a List
|
||||
DynamicList<char> release()
|
||||
{
|
||||
DynamicList<char> chars(buffer_type::release());
|
||||
stream_type::clear(); // Clear old errors
|
||||
return chars;
|
||||
}
|
||||
|
||||
//- Some information about the input buffer position/capacity
|
||||
void debug_info(Ostream& os) const
|
||||
{
|
||||
os << "get="
|
||||
<< input_pos() << '/' << capacity();
|
||||
os << "get=" << input_pos() << '/' << capacity();
|
||||
}
|
||||
};
|
||||
|
||||
@ -252,7 +273,7 @@ public:
|
||||
//- Move construct from List
|
||||
explicit ICharStream
|
||||
(
|
||||
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
|
||||
List<char>&& buffer,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
@ -296,6 +317,19 @@ public:
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> list() const { return stream_.list(); }
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(stream_.view())
|
||||
{
|
||||
return stream_.view();
|
||||
}
|
||||
|
||||
//- For IStringStream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
auto str() const -> decltype(stream_.str())
|
||||
{
|
||||
return stream_.str();
|
||||
}
|
||||
|
||||
//- Reset content (copy)
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
{
|
||||
@ -303,14 +337,14 @@ public:
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
stream_.swap(other);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
@ -318,6 +352,14 @@ public:
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Reset stream and return contents as a List
|
||||
DynamicList<char> release()
|
||||
{
|
||||
DynamicList<char> chars(stream_.release());
|
||||
syncState();
|
||||
return chars;
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind() override
|
||||
{
|
||||
|
@ -64,9 +64,9 @@ See Also
|
||||
#ifndef Foam_ISpanStream_H
|
||||
#define Foam_ISpanStream_H
|
||||
|
||||
#include "memoryStreamBuffer.H"
|
||||
#include "UList.H"
|
||||
#include "ISstream.H"
|
||||
#include "memoryStreamBuffer.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -117,12 +117,28 @@ public:
|
||||
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))
|
||||
// {}
|
||||
#if __cplusplus >= 201703L
|
||||
//- Construct (shallow copy) from std::string_view content
|
||||
explicit ispanstream(std::string_view s)
|
||||
{
|
||||
buffer_type(const_cast<char*>(s.data()), s.size()),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
}
|
||||
#endif
|
||||
|
||||
//- Construct (shallow copy) from span character content
|
||||
explicit ispanstream(stdFoam::span<char> s)
|
||||
:
|
||||
buffer_type(const_cast<char*>(s.data()), s.size()),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
//- Construct (shallow copy) from span character content
|
||||
explicit ispanstream(stdFoam::span<const char> s)
|
||||
:
|
||||
buffer_type(const_cast<char*>(s.data()), s.size()),
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
@ -149,7 +165,28 @@ public:
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return buffer_type::span_list();
|
||||
return UList<char>
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
label(buffer_type::size_bytes())
|
||||
);
|
||||
}
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(buffer_type::view())
|
||||
{
|
||||
return buffer_type::view();
|
||||
}
|
||||
|
||||
//- For istringstream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
std::string str() const
|
||||
{
|
||||
return std::string
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
buffer_type::size_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
@ -259,17 +296,6 @@ public:
|
||||
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
|
||||
@ -281,6 +307,38 @@ public:
|
||||
ISpanStream(buffer.cdata(), buffer.size(), streamOpt)
|
||||
{}
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//- Construct (shallow copy) from std::string_view content
|
||||
explicit ISpanStream
|
||||
(
|
||||
std::string_view s,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(s.data(), s.size(), streamOpt)
|
||||
{}
|
||||
#endif
|
||||
|
||||
//- Construct (shallow copy) from span character content
|
||||
explicit ISpanStream
|
||||
(
|
||||
stdFoam::span<const char> s,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(s.data(), s.size(), streamOpt)
|
||||
{}
|
||||
|
||||
//- Construct (shallow copy) from span character content
|
||||
explicit ISpanStream
|
||||
(
|
||||
stdFoam::span<char> s,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
ISpanStream(s.data(), s.size(), streamOpt)
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -300,10 +358,22 @@ public:
|
||||
//- 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(); }
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(stream_.view())
|
||||
{
|
||||
return stream_.view();
|
||||
}
|
||||
|
||||
//- For IStringStream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
auto str() const -> decltype(stream_.str())
|
||||
{
|
||||
return stream_.str();
|
||||
}
|
||||
|
||||
//- Reset input area, position to buffer start and clear errors
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
{
|
||||
@ -318,6 +388,29 @@ public:
|
||||
syncState();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//- Reset input area to use data from a std::string_view
|
||||
void reset(std::string_view s)
|
||||
{
|
||||
stream_.reset(s.data(), s.size());
|
||||
syncState();
|
||||
}
|
||||
#endif
|
||||
|
||||
//- Reset input area to use data from span character content
|
||||
void reset(stdFoam::span<char> s)
|
||||
{
|
||||
stream_.reset(s.data(), s.size());
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Reset input area to use data from span character content
|
||||
void reset(stdFoam::span<const char> s)
|
||||
{
|
||||
stream_.reset(s.data(), s.size());
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind() override
|
||||
{
|
||||
|
@ -124,12 +124,6 @@ public:
|
||||
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()
|
||||
{
|
||||
@ -137,14 +131,41 @@ public:
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
//- Span of the current output characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return UList<char>
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
label(buffer_type::size_bytes())
|
||||
);
|
||||
}
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(buffer_type::view())
|
||||
{
|
||||
return buffer_type::view();
|
||||
}
|
||||
|
||||
//- For ostringstream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
std::string str() const
|
||||
{
|
||||
return std::string
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
buffer_type::size_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
buffer_type::swap(other);
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
@ -152,11 +173,18 @@ public:
|
||||
stream_type::clear(); // Clear old errors
|
||||
}
|
||||
|
||||
//- Reset buffer and return contents
|
||||
DynamicList<char> release()
|
||||
{
|
||||
DynamicList<char> chars(buffer_type::release());
|
||||
stream_type::clear(); // Clear old errors
|
||||
return chars;
|
||||
}
|
||||
|
||||
//- Some information about the output buffer position/capacity
|
||||
void debug_info(Ostream& os) const
|
||||
{
|
||||
os << "put="
|
||||
<< output_pos() << '/' << capacity();
|
||||
os << "put=" << output_pos() << '/' << capacity();
|
||||
}
|
||||
};
|
||||
|
||||
@ -214,19 +242,7 @@ public:
|
||||
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
|
||||
//- Move construct from a List of initial storage
|
||||
explicit OCharStream
|
||||
(
|
||||
::Foam::List<char>&& buffer,
|
||||
@ -238,7 +254,8 @@ public:
|
||||
stream_.swap(buffer);
|
||||
}
|
||||
|
||||
//- Move construct from a DynamicList (uses entire capacity)
|
||||
//- Move construct from a DynamicList of initial storage
|
||||
//- (uses entire capacity)
|
||||
template<int SizeMin>
|
||||
explicit OCharStream
|
||||
(
|
||||
@ -272,14 +289,27 @@ public:
|
||||
//- Span of the current output characters (is modifiable!)
|
||||
UList<char> list() const { return stream_.list(); }
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(stream_.view())
|
||||
{
|
||||
return stream_.view();
|
||||
}
|
||||
|
||||
//- For OStringStream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
auto str() const -> decltype(stream_.str())
|
||||
{
|
||||
return stream_.str();
|
||||
}
|
||||
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
stream_.swap(other);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
@ -287,6 +317,14 @@ public:
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Reset buffer and return contents
|
||||
DynamicList<char> release()
|
||||
{
|
||||
DynamicList<char> chars(stream_.release());
|
||||
syncState();
|
||||
return chars;
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
virtual void rewind()
|
||||
{
|
||||
|
@ -132,13 +132,6 @@ public:
|
||||
stream_type(static_cast<buffer_type*>(this))
|
||||
{}
|
||||
|
||||
// //- Construct (shallow copy) from span character content
|
||||
// ospanstream(stdFoam::span<char> s)
|
||||
// :
|
||||
// buffer_type(const_cast<char*>(s.data()), s.size()),
|
||||
// stream_type(static_cast<buffer_type*>(this))
|
||||
// {}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
@ -157,7 +150,28 @@ public:
|
||||
//- Span of the current output characters (is modifiable!)
|
||||
UList<char> list() const
|
||||
{
|
||||
return buffer_type::span_list();
|
||||
return UList<char>
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
label(buffer_type::size_bytes())
|
||||
);
|
||||
}
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(buffer_type::view())
|
||||
{
|
||||
return buffer_type::view();
|
||||
}
|
||||
|
||||
//- For ostringstream compatibility, return the buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
std::string str() const
|
||||
{
|
||||
return std::string
|
||||
(
|
||||
buffer_type::data_bytes(),
|
||||
buffer_type::size_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
@ -222,7 +236,6 @@ protected:
|
||||
Class OSpanStream Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An OSstream attached to an unallocated external buffer
|
||||
class OSpanStream
|
||||
:
|
||||
public Detail::OSpanStreamAllocator,
|
||||
@ -269,17 +282,6 @@ public:
|
||||
stream_.reset(buffer, nbytes);
|
||||
}
|
||||
|
||||
//- Construct using data area from a List and number of bytes
|
||||
OSpanStream
|
||||
(
|
||||
::Foam::UList<char>& buffer,
|
||||
size_t nbytes,
|
||||
IOstreamOption streamOpt = IOstreamOption()
|
||||
)
|
||||
:
|
||||
OSpanStream(buffer.data(), nbytes, streamOpt)
|
||||
{}
|
||||
|
||||
//- Construct using data area from a List and its inherent storage size
|
||||
explicit OSpanStream
|
||||
(
|
||||
@ -321,6 +323,19 @@ public:
|
||||
//- Span of the current output characters (is modifiable!)
|
||||
UList<char> list() const { return stream_.list(); }
|
||||
|
||||
//- A string_view (c++17) or span view (older c++) of buffer contents
|
||||
auto view() const -> decltype(stream_.view())
|
||||
{
|
||||
return stream_.view();
|
||||
}
|
||||
|
||||
//- For OStringStream compatibility, return buffer as string copy.
|
||||
// Use sparingly - it creates a full copy!!
|
||||
auto str() const -> decltype(stream_.str())
|
||||
{
|
||||
return stream_.str();
|
||||
}
|
||||
|
||||
//- Reset the put area
|
||||
void reset(char* buffer, size_t nbytes)
|
||||
{
|
||||
|
@ -36,10 +36,9 @@ Description
|
||||
#define Foam_memoryStreamBuffer_H
|
||||
|
||||
#include "stdFoam.H" // For span
|
||||
#include "UList.H"
|
||||
#include "DynamicList.H"
|
||||
|
||||
#include <memory>
|
||||
#include <sstream> // Possibly want stringstream too...
|
||||
#include <type_traits>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -208,17 +207,23 @@ public:
|
||||
return (gptr() < egptr()) ? (egptr() - gptr()) : 0;
|
||||
}
|
||||
|
||||
//- Span of the input characters (is modifiable!)
|
||||
UList<char> span_list() const
|
||||
{
|
||||
return UList<char>(eback(), (egptr() - eback()));
|
||||
}
|
||||
//- The span data (start of input characters)
|
||||
char* data_bytes() const { return eback(); }
|
||||
|
||||
// //- The span of input characters (is modifiable!)
|
||||
// stdFoam::span<char> span() const
|
||||
// {
|
||||
// return stdFoam::span<char>(eback(), (egptr() - eback()));
|
||||
// }
|
||||
//- The span size (number of input characters)
|
||||
std::streamsize size_bytes() const { return (egptr() - eback()); }
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
std::string_view view() const
|
||||
{
|
||||
return std::string_view(data_bytes(), size_bytes());
|
||||
}
|
||||
#else
|
||||
stdFoam::span<const char> view() const
|
||||
{
|
||||
return stdFoam::span<const char>(data_bytes(), size_bytes());
|
||||
}
|
||||
#endif
|
||||
|
||||
//- Some information about the input buffer position/capacity
|
||||
void info(Ostream& os) const
|
||||
@ -273,7 +278,7 @@ public:
|
||||
template<int SizeMin>
|
||||
in_dynamic(::Foam::DynamicList<char,SizeMin>&& buffer)
|
||||
{
|
||||
storage_.transfer(buffer);
|
||||
storage_.transfer(buffer); // Implies shrink_to_fit
|
||||
sync_gbuffer();
|
||||
}
|
||||
|
||||
@ -302,24 +307,29 @@ public:
|
||||
sync_gbuffer();
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
void swap(::Foam::List<char>& other)
|
||||
//- Exchange buffer content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
storage_.swap(other); // Swap contents
|
||||
other.swap(storage_); // Swap contents
|
||||
sync_gbuffer();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
//- Exchange buffer content and parameter contents, reset positions
|
||||
template<int SizeMin>
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
List<char> tmp(std::move(storage_));
|
||||
|
||||
other.shrink(); // Use addressed length only
|
||||
storage_.transfer(other);
|
||||
other.transfer(tmp);
|
||||
// NB: not storage_.swap(other)! - incorrect slicing
|
||||
other.swap(storage_); // Swap contents: implies shrink_to_fit
|
||||
sync_gbuffer();
|
||||
}
|
||||
|
||||
//- Reset buffer and return contents
|
||||
DynamicList<char> release()
|
||||
{
|
||||
DynamicList<char> chars(std::move(storage_));
|
||||
sync_gbuffer();
|
||||
return chars;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -387,17 +397,23 @@ public:
|
||||
//- The put buffer capacity
|
||||
std::streamsize span_capacity() const { return (epptr() - pbase()); }
|
||||
|
||||
//- Span of the output characters (is modifiable!)
|
||||
UList<char> span_list() const
|
||||
{
|
||||
return UList<char>(pbase(), (pptr() - pbase()));
|
||||
}
|
||||
//- The span data (start of output characters)
|
||||
char* data_bytes() const { return pbase(); }
|
||||
|
||||
//- The span of output characters (is modifiable!)
|
||||
// stdFoam::span<char> span() const
|
||||
// {
|
||||
// return stdFoam::span<char>(pbase(), (pptr() - pbase()));
|
||||
// }
|
||||
//- The span size (size of output buffer)
|
||||
std::streamsize size_bytes() const { return (pptr() - pbase()); }
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
std::string_view view() const
|
||||
{
|
||||
return std::string_view(data_bytes(), size_bytes());
|
||||
}
|
||||
#else
|
||||
stdFoam::span<const char> view() const
|
||||
{
|
||||
return stdFoam::span<const char>(data_bytes(), size_bytes());
|
||||
}
|
||||
#endif
|
||||
|
||||
//- Some information about the output buffer position/capacity
|
||||
void info(Ostream& os) const
|
||||
@ -532,7 +548,7 @@ public:
|
||||
}
|
||||
|
||||
//- Shrink storage to addressed storage
|
||||
inline void shrink()
|
||||
void shrink()
|
||||
{
|
||||
const auto cur = span_tellp(); // Addressed length
|
||||
|
||||
@ -541,29 +557,39 @@ public:
|
||||
pbump(cur);
|
||||
}
|
||||
|
||||
//- Transfer list contents to List buffer
|
||||
inline void swap(List<char>& other)
|
||||
//- Exchange buffer content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
{
|
||||
const auto cur = span_tellp(); // Addressed length
|
||||
|
||||
storage_.swap(other); // Swap contents
|
||||
other.resize(cur); // Adjust to addressed length
|
||||
const auto cur = span_tellp(); // Output length
|
||||
other.swap(storage_);
|
||||
other.resize(cur); // Truncate to output length
|
||||
sync_pbuffer();
|
||||
}
|
||||
|
||||
//- Transfer list contents to a DynamicList buffer
|
||||
//- Exchange buffer content and parameter contents, reset positions
|
||||
template<int SizeMin>
|
||||
inline void swap(DynamicList<char,SizeMin>& other)
|
||||
void swap(DynamicList<char,SizeMin>& other)
|
||||
{
|
||||
const auto cur = span_tellp(); // Addressed length
|
||||
List<char> tmp(std::move(storage_));
|
||||
const auto cur = span_tellp(); // Output length
|
||||
|
||||
other.resize(other.capacity()); // Use entire space
|
||||
storage_.transfer(other);
|
||||
other.transfer(tmp);
|
||||
other.resize(cur); // Adjust to addressed length
|
||||
other.swap(storage_); // NB: not storage_.swap(other)
|
||||
other.resize(cur); // Restrict to output length
|
||||
sync_pbuffer();
|
||||
}
|
||||
|
||||
//- Reset buffer and return contents as a DynamicList.
|
||||
//- The list size corresponds to the region of output.
|
||||
DynamicList<char> release()
|
||||
{
|
||||
const auto cur = span_tellp(); // Output length
|
||||
DynamicList<char> chars(std::move(storage_));
|
||||
chars.resize(cur); // Restrict to output length
|
||||
|
||||
if (chars.empty()) chars.clearStorage(); // Can destroy now
|
||||
sync_pbuffer();
|
||||
return chars;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user