diff --git a/src/io/finalizing_ostream.hpp b/src/io/finalizing_ostream.hpp new file mode 100644 index 00000000..c8462247 --- /dev/null +++ b/src/io/finalizing_ostream.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include + +class finalizing_ostream final : public std::ostream { +public: + finalizing_ostream( + std::unique_ptr inner, + std::function)> on_destruction + ) + : std::ostream(inner->rdbuf()), + innerStream(std::move(inner)), + onDestruction(on_destruction) { + } + + finalizing_ostream(const finalizing_ostream&) = delete; + finalizing_ostream& operator=(const finalizing_ostream&) = delete; + + finalizing_ostream(finalizing_ostream&& other) noexcept + : std::ostream(std::move(other)), + innerStream(std::move(other.innerStream)), + onDestruction(std::move(other.onDestruction)) { + other.onDestruction = nullptr; + } + + finalizing_ostream& operator=(finalizing_ostream&& other) noexcept { + if (this != &other) { + std::ostream::operator=(std::move(other)); + innerStream = std::move(other.innerStream); + onDestruction = std::move(other.onDestruction); + other.onDestruction = nullptr; + } + return *this; + } + + ~finalizing_ostream() { + if (onDestruction) { + onDestruction(std::move(innerStream)); + } + } + +private: + std::unique_ptr innerStream; + std::function)> onDestruction; +};