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.


Reply via email to