5#include "Stroika/Foundation/Execution/Exceptions.h"
7#include "Stroika/Foundation/Execution/Throw.h"
8#include "Stroika/Foundation/Streams/InternallySynchronizedOutputStream.h"
10namespace Stroika::Foundation::Streams::iostream::OutputStreamFromStdOStream {
13 template <
typename ELEMENT_TYPE,
typename BASIC_OSTREAM_ELEMENT_TYPE,
typename BASIC_OSTREAM_TRAITS_TYPE>
14 class Rep_ :
public OutputStream::IRep<ELEMENT_TYPE> {
19 Rep_ (basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& originalStream)
20 : fOriginalStreamRef_{originalStream}
25 virtual bool IsSeekable ()
const override
30 virtual void CloseWrite ()
override
34 Ensure (not IsOpenWrite ());
36 virtual bool IsOpenWrite ()
const override
45 Require (IsOpenWrite ());
46 return fOriginalStreamRef_.rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::out);
48 virtual SeekOffsetType SeekWrite (Whence whence, SignedSeekOffsetType offset)
override
51 Require (IsOpenWrite ());
54 fOriginalStreamRef_.seekp (offset, ios::beg);
57 fOriginalStreamRef_.seekp (offset, ios::cur);
60 fOriginalStreamRef_.seekp (offset, ios::end);
63 return fOriginalStreamRef_.tellp ();
65 virtual void Write (span<const ELEMENT_TYPE> elts)
override
67 Require (not elts.empty ());
68 Require (IsOpenWrite ());
71 using StreamElementType = BASIC_OSTREAM_ELEMENT_TYPE;
72 fOriginalStreamRef_.write (
reinterpret_cast<const StreamElementType*
> (elts.data ()), elts.size ());
73 if (fOriginalStreamRef_.fail ()) [[unlikely]] {
74 static const Execution::RuntimeErrorException kException_{
"Failed to write from ostream"sv};
78 virtual void Flush ()
override
81 Require (IsOpenWrite ());
82 fOriginalStreamRef_.flush ();
83 if (fOriginalStreamRef_.fail ()) [[unlikely]] {
84 static const Execution::RuntimeErrorException kException_{
"Failed to flush ostream"sv};
90 basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& fOriginalStreamRef_;
91 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
100 template <
typename ELEMENT_TYPE,
typename BASIC_OSTREAM_ELEMENT_TYPE,
typename BASIC_OSTREAM_TRAITS_TYPE>
101 inline auto New (basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& originalStream) ->
Ptr<ELEMENT_TYPE>
102 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, char>) or
103 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, wchar_t>))
105 return Ptr<ELEMENT_TYPE>{make_shared<Private_::Rep_<ELEMENT_TYPE, BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>> (originalStream)};
107 template <
typename ELEMENT_TYPE,
typename BASIC_OSTREAM_ELEMENT_TYPE,
typename BASIC_OSTREAM_TRAITS_TYPE>
109 basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& originalStream) ->
Ptr<ELEMENT_TYPE>
110 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, char>) or
111 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, wchar_t>))
113 switch (internallySynchronized) {
114 case Execution::eInternallySynchronized:
115 return InternallySynchronizedOutputStream::New<Private_::Rep_<ELEMENT_TYPE, BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>> (
117 case Execution::eNotKnownInternallySynchronized:
118 return New<ELEMENT_TYPE> (originalStream);
#define RequireNotReached()
typename OutputStream::Ptr< ELEMENT_TYPE > Ptr
shared_lock< const AssertExternallySynchronizedMutex > ReadContext
Instantiate AssertExternallySynchronizedMutex::ReadContext to designate an area of code where protect...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...