From 41a5d654eb037df21e4588ca749048cb4065658e Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Fri, 16 Oct 2020 10:58:03 +0300 Subject: VS 2013 workarounds --- include/winapi/process.hpp | 37 ++++++++++++++++++++++++++- include/winapi/stream.hpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/include/winapi/process.hpp b/include/winapi/process.hpp index 22317ca..2614c0f 100644 --- a/include/winapi/process.hpp +++ b/include/winapi/process.hpp @@ -9,6 +9,8 @@ #include "handle.hpp" #include "stream.hpp" +#include + #include namespace winapi { @@ -16,11 +18,31 @@ namespace winapi { class Process { public: struct IO { + IO() = default; + + void close(); + process::Stdin std_in; process::Stdout std_out; process::Stderr std_err; - void close(); + // VS 2013 won't generate these automatically. + + IO(IO&& other) BOOST_NOEXCEPT_OR_NOTHROW { swap(other); } + + IO& operator=(IO other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + return *this; + } + + void swap(IO& other) BOOST_NOEXCEPT_OR_NOTHROW { + using std::swap; + swap(std_in, other.std_in); + swap(std_out, other.std_out); + swap(std_err, other.std_err); + } + + IO(const IO&) = delete; }; static Process create(const CommandLine&); @@ -34,4 +56,17 @@ private: Handle m_handle; }; +inline void swap(Process::IO& a, Process::IO& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + } // namespace winapi + +namespace std { + +template <> +inline void swap(winapi::Process::IO& a, winapi::Process::IO& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +} // namespace std diff --git a/include/winapi/stream.hpp b/include/winapi/stream.hpp index cf85508..6b4bc38 100644 --- a/include/winapi/stream.hpp +++ b/include/winapi/stream.hpp @@ -8,6 +8,8 @@ #include "handle.hpp" #include "pipe.hpp" +#include + #include #include @@ -18,25 +20,87 @@ struct Stream { Stream(Handle&& handle) : handle{std::move(handle)} {} Handle handle; + + // VS 2013 won't generate these automatically. + + Stream(Stream&& other) BOOST_NOEXCEPT_OR_NOTHROW { swap(other); } + + Stream& operator=(Stream other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + return *this; + } + + void swap(Stream& other) BOOST_NOEXCEPT_OR_NOTHROW { + using std::swap; + swap(handle, other.handle); + } + + Stream(const Stream&) = delete; }; +inline void swap(Stream& a, Stream& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + struct Stdin : Stream { Stdin(); explicit Stdin(const std::string& file); explicit Stdin(Pipe&); + + // VS 2013 won't generate these automatically. + + Stdin(Stdin&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} + + Stdin& operator=(Stdin other) BOOST_NOEXCEPT_OR_NOTHROW { + Stream::operator=(std::move(other)); + return *this; + } + + Stdin(const Stdin&) = delete; }; struct Stdout : Stream { Stdout(); explicit Stdout(const std::string& file); explicit Stdout(Pipe&); + + // VS 2013 won't generate these automatically. + + Stdout(Stdout&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} + + Stdout& operator=(Stdout other) BOOST_NOEXCEPT_OR_NOTHROW { + Stream::operator=(std::move(other)); + return *this; + } + + Stdout(const Stdout&) = delete; }; struct Stderr : Stream { Stderr(); explicit Stderr(const std::string& file); explicit Stderr(Pipe&); + + // VS 2013 won't generate these automatically. + + Stderr(Stderr&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} + + Stderr& operator=(Stderr other) BOOST_NOEXCEPT_OR_NOTHROW { + Stream::operator=(std::move(other)); + return *this; + } + + Stderr(const Stderr&) = delete; }; } // namespace process } // namespace winapi + +namespace std { + +template <> +inline void swap(winapi::process::Stream& a, winapi::process::Stream& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +} // namespace std -- cgit v1.2.3