5#include "Stroika/Foundation/Execution/Exceptions.h"
7#include "Stroika/Foundation/Execution/Throw.h"
9#include "Stroika/Foundation/Streams/InternallySynchronizedOutputStream.h"
11namespace Stroika::Foundation::Streams::iostream::OutputStreamFromStdOStream {
14 template <
typename ELEMENT_TYPE,
typename BASIC_OSTREAM_ELEMENT_TYPE,
typename BASIC_OSTREAM_TRAITS_TYPE>
15 class Rep_ :
public OutputStream::IRep<ELEMENT_TYPE> {
20 Rep_ (basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& originalStream)
21 : fOriginalStreamRef_{originalStream}
26 virtual bool IsSeekable ()
const override
31 virtual void CloseWrite ()
override
35 Ensure (not IsOpenWrite ());
37 virtual bool IsOpenWrite ()
const override
46 Require (IsOpenWrite ());
47 return fOriginalStreamRef_.rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::out);
49 virtual SeekOffsetType SeekWrite (Whence whence, SignedSeekOffsetType offset)
override
52 Require (IsOpenWrite ());
55 fOriginalStreamRef_.seekp (offset, ios::beg);
58 fOriginalStreamRef_.seekp (offset, ios::cur);
61 fOriginalStreamRef_.seekp (offset, ios::end);
64 return fOriginalStreamRef_.tellp ();
66 virtual void Write (span<const ELEMENT_TYPE> elts)
override
68 Require (not elts.empty ());
69 Require (IsOpenWrite ());
72 using StreamElementType = BASIC_OSTREAM_ELEMENT_TYPE;
73 fOriginalStreamRef_.write (
reinterpret_cast<const StreamElementType*
> (elts.data ()), elts.size ());
74 if (fOriginalStreamRef_.fail ()) [[unlikely]] {
75 static const Execution::RuntimeErrorException kException_{
"Failed to write from ostream"sv};
79 virtual void Flush ()
override
82 Require (IsOpenWrite ());
83 fOriginalStreamRef_.flush ();
84 if (fOriginalStreamRef_.fail ()) [[unlikely]] {
85 static const Execution::RuntimeErrorException kException_{
"Failed to flush ostream"sv};
91 basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& fOriginalStreamRef_;
92 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
101 template <
typename ELEMENT_TYPE,
typename BASIC_OSTREAM_ELEMENT_TYPE,
typename BASIC_OSTREAM_TRAITS_TYPE>
102 inline auto New (basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& originalStream) ->
Ptr<ELEMENT_TYPE>
103 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, char>) or
104 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, wchar_t>))
106 return Ptr<ELEMENT_TYPE>{Memory::MakeSharedPtr<Private_::Rep_<ELEMENT_TYPE, BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>> (originalStream)};
108 template <
typename ELEMENT_TYPE,
typename BASIC_OSTREAM_ELEMENT_TYPE,
typename BASIC_OSTREAM_TRAITS_TYPE>
110 basic_ostream<BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>& originalStream) ->
Ptr<ELEMENT_TYPE>
111 requires ((same_as<ELEMENT_TYPE, byte> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, char>) or
112 (same_as<ELEMENT_TYPE, Characters::Character> and same_as<BASIC_OSTREAM_ELEMENT_TYPE, wchar_t>))
114 switch (internallySynchronized) {
115 case Execution::eInternallySynchronized:
116 return InternallySynchronizedOutputStream::New<Private_::Rep_<ELEMENT_TYPE, BASIC_OSTREAM_ELEMENT_TYPE, BASIC_OSTREAM_TRAITS_TYPE>> (
118 case Execution::eNotKnownInternallySynchronized:
119 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...