Switch pimpl away from std::unique_ptr due to msvc awfulness

This commit is contained in:
Jeremy Rifkin 2025-02-01 16:59:31 -06:00
parent c6021fe8f5
commit 3cb7ef4ec5
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
3 changed files with 27 additions and 8 deletions

View File

@ -9,8 +9,9 @@
namespace cpptrace {
class CPPTRACE_EXPORT formatter {
class CPPTRACE_EXPORT impl;
std::unique_ptr<impl> 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();

View File

@ -212,14 +212,25 @@ namespace cpptrace {
}
};
formatter::formatter() : pimpl(std::unique_ptr<impl>(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<impl>(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<impl>(new impl(*other.pimpl));
if(pimpl) {
delete pimpl;
}
pimpl = new impl(*other.pimpl);
return *this;
}

View File

@ -189,6 +189,13 @@ namespace detail {
return static_cast<U>(v);
}
template<typename T, typename U = T>
T exchange(T& obj, U&& value) {
T old = std::move(obj);
obj = std::forward<U>(value);
return old;
}
struct monostate {};
// TODO: Rework some stuff here. Not sure deleters should be optional or moved.