On 15/10/20 07:46 -0700, Thomas Rodgers wrote:
+ template <typename _CharT, typename _Traits = char_traits<_CharT>,
+ typename _Alloc = allocator<_CharT>>
+ class basic_osyncstream : public basic_ostream<_CharT, _Traits>
+ {
+ public:
+ // Types:
+ using char_type = _CharT;
+ using traits_type = _Traits;
+ using allocator_type = _Alloc;
+ using int_type = typename traits_type::int_type;
+ using pos_type = typename traits_type::pos_type;
+ using off_type = typename traits_type::off_type;
+ using syncbuf_type = basic_syncbuf<_CharT, _Traits, _Alloc>;
+ using streambuf_type = typename syncbuf_type::streambuf_type;
+
+ using __ostream_type = basic_ostream<_CharT, _Traits>;
+
+ private:
+ syncbuf_type _M_syncbuf;
+
+ public:
+ basic_osyncstream(streambuf_type* __buf, const allocator_type& __a)
+ : _M_syncbuf(__buf, __a)
+ { this->init(&_M_syncbuf); }
+
+ explicit basic_osyncstream(streambuf_type* __buf)
+ : _M_syncbuf(__buf)
+ { this->init(&_M_syncbuf); }
+
+ basic_osyncstream(basic_ostream<char_type, traits_type>& __os,
+ const allocator_type& __a)
+ : basic_osyncstream(__os.rdbuf(), __a)
+ { this->init(&_M_syncbuf); }
+
+ explicit basic_osyncstream(basic_ostream<char_type, traits_type>& __os)
+ : basic_osyncstream(__os.rdbuf())
+ { this->init(&_M_syncbuf); }
+
+ basic_osyncstream(basic_osyncstream&& __rhs) noexcept
+ : __ostream_type(std::move(__rhs)),
+ _M_syncbuf(std::move(__rhs._M_syncbuf))
+ { __ostream_type::set_rdbuf(&_M_syncbuf); }
+
+ ~basic_osyncstream() = default;
+
+ basic_osyncstream& operator=(basic_osyncstream&& __rhs) noexcept
+ {
+ if (&__rhs != this)
Rather than adding std::__addressof here, I'm not sure we need the
check for self-assignment at all. The ostream base's move assignment
is safe on self-assignment, and the syncbuf is too (because it checks
for it).
+ {
+ __ostream_type::operator=(std::move(__rhs));
+ _M_syncbuf = std::move(__rhs._M_syncbuf);
+ __ostream_type::set_rdbuf(&_M_syncbuf);
I think this set_rdbuf is not needed.
I think the move assignment could be defaulted.
+ }
+ return *this;
+ }
+
+ syncbuf_type* rdbuf() const noexcept
+ { return const_cast<syncbuf_type*>(&_M_syncbuf); }
+
+ streambuf_type* get_wrapped() const noexcept
+ { return _M_syncbuf.get_wrapped(); }
+
+ void emit()
+ { _M_syncbuf.emit(); }
This needs to check the result of _M_syncbuf.emit() and possibly set
failbit.