// ReSharper disable CppInconsistentNaming // ReSharper disable IdentifierTypo #pragma once #include "Utils/ClassUtils.h" #include #include #include #include template class basic_objbuf : public std::basic_streambuf { public: _NODISCARD virtual bool is_open() const = 0; virtual bool close() = 0; }; template class basic_objstream : public std::basic_iostream { public: using mybase = std::basic_iostream; using myob = basic_objbuf; using myios = std::basic_ios; explicit basic_objstream(std::unique_ptr objbuf) : std::basic_iostream(objbuf.get()), m_ob(std::move(objbuf)) { assert(m_ob); } explicit basic_objstream(basic_objstream&& right) noexcept : std::basic_iostream(right), m_ob(std::move(right.m_ob)) { assert(m_ob != nullptr); } basic_objstream(const basic_objstream& other) = delete; basic_objstream& operator=(const basic_objstream& other) = delete; ~basic_objstream() override { if (m_ob) m_ob->close(); } void swap(basic_objstream& right) noexcept { if (this != std::addressof(right)) { mybase::swap(right); m_ob = std::move(right.m_ob); } } basic_objstream& operator=(basic_objstream&& other) noexcept { swap(other); return *this; } // ReSharper disable once CppHidingFunction _NODISCARD myob* rdbuf() const { return const_cast(m_ob.get()); } _NODISCARD bool is_open() const { return m_ob->is_open(); } void close() { if (!m_ob->close()) { myios::setstate(std::ios_base::failbit); } } protected: std::unique_ptr m_ob; }; template class basic_iobjstream : public std::basic_istream { public: using mybase = std::basic_istream; using myob = basic_objbuf; using myios = std::basic_ios; explicit basic_iobjstream(std::unique_ptr objbuf) : std::basic_istream(objbuf.get()), m_ob(std::move(objbuf)) { assert(m_ob); } explicit basic_iobjstream(basic_iobjstream&& right) noexcept : std::basic_istream(right), m_ob(std::move(right.m_ob)) { assert(m_ob != nullptr); } basic_iobjstream(const basic_iobjstream& other) = delete; basic_iobjstream& operator=(const basic_iobjstream& other) = delete; ~basic_iobjstream() override = default; void swap(basic_iobjstream& right) noexcept { if (this != std::addressof(right)) { mybase::swap(right); m_ob = std::move(right.m_ob); } } basic_iobjstream& operator=(basic_iobjstream&& other) noexcept { swap(other); return *this; } // ReSharper disable once CppHidingFunction _NODISCARD myob* rdbuf() const { return const_cast(m_ob.get()); } _NODISCARD bool is_open() const { return m_ob->is_open(); } void close() { if (!m_ob->close()) { myios::setstate(std::ios_base::failbit); } } protected: std::unique_ptr m_ob; }; template class basic_oobjstream : public std::basic_ostream { public: using mybase = std::basic_ostream; using myob = basic_objbuf; using myios = std::basic_ios; explicit basic_oobjstream(std::unique_ptr objbuf) : std::basic_ostream(objbuf.get()), m_ob(std::move(objbuf)) { assert(m_ob); } explicit basic_oobjstream(basic_oobjstream&& right) noexcept : std::basic_ostream(right), m_ob(std::move(right.m_ob)) { assert(m_ob != nullptr); } ~basic_oobjstream() override = default; basic_oobjstream(const basic_oobjstream& other) = delete; basic_oobjstream& operator=(const basic_oobjstream& other) = delete; void swap(basic_oobjstream& right) noexcept { if (this != std::addressof(right)) { mybase::swap(right); m_ob = std::move(right.m_ob); } } basic_oobjstream& operator=(basic_oobjstream&& other) noexcept { swap(other); return *this; } // ReSharper disable once CppHidingFunction _NODISCARD myob* rdbuf() const { return const_cast(m_ob.get()); } _NODISCARD bool is_open() const { return m_ob->is_open(); } void close() { if (!m_ob->close()) { myios::setstate(std::ios_base::failbit); } } protected: std::unique_ptr m_ob; }; using objbuf = basic_objbuf>; using objstream = basic_objstream>; using iobjstream = basic_iobjstream>; using oobjstream = basic_oobjstream>;