diff --git a/include/cpptrace/formatting.hpp b/include/cpptrace/formatting.hpp index bec8b89..7ddf4ea 100644 --- a/include/cpptrace/formatting.hpp +++ b/include/cpptrace/formatting.hpp @@ -9,8 +9,9 @@ namespace cpptrace { class CPPTRACE_EXPORT formatter { - class CPPTRACE_EXPORT impl; - std::unique_ptr pimpl; + class impl; + // can't be a std::unique_ptr due to msvc awfulness with dllimport/dllexport and https://stackoverflow.com/q/4145605/15675011 + impl* pimpl; public: formatter(); diff --git a/src/formatting.cpp b/src/formatting.cpp index bfcf6e7..eb17bbb 100644 --- a/src/formatting.cpp +++ b/src/formatting.cpp @@ -212,14 +212,25 @@ namespace cpptrace { } }; - formatter::formatter() : pimpl(std::unique_ptr(new impl)) {} - formatter::~formatter() = default; + formatter::formatter() : pimpl(new impl) {} + formatter::~formatter() { + delete pimpl; + } - formatter::formatter(formatter&&) = default; - formatter::formatter(const formatter& other) : pimpl(std::unique_ptr(new impl(*other.pimpl))) {} - formatter& formatter::operator=(formatter&&) = default; + formatter::formatter(formatter&& other) : pimpl(detail::exchange(other.pimpl, nullptr)) {} + formatter::formatter(const formatter& other) : pimpl(new impl(*other.pimpl)) {} + formatter& formatter::operator=(formatter&& other) { + if(pimpl) { + delete pimpl; + } + pimpl = detail::exchange(other.pimpl, nullptr); + return *this; + } formatter& formatter::operator=(const formatter& other) { - pimpl = std::unique_ptr(new impl(*other.pimpl)); + if(pimpl) { + delete pimpl; + } + pimpl = new impl(*other.pimpl); return *this; } diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index f4af8f3..a81521a 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -189,6 +189,13 @@ namespace detail { return static_cast(v); } + template + T exchange(T& obj, U&& value) { + T old = std::move(obj); + obj = std::forward(value); + return old; + } + struct monostate {}; // TODO: Rework some stuff here. Not sure deleters should be optional or moved.