commit c00d0b4d3c6d0a3eed86310c265f620c4a883264
parent 5f86adcc15715188678dcda4bcca1e09de7f32f7
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Fri, 22 Sep 2023 21:21:01 +0100
type-erased-unique_ptr: Add example of type erasure
Diffstat:
1 file changed, 80 insertions(+), 0 deletions(-)
diff --git a/src/type-erased-unique_ptr.cpp b/src/type-erased-unique_ptr.cpp
@@ -0,0 +1,79 @@
+#include <utility>
+#include <iostream>
+
+template <typename T = void>
+struct unique_ptr
+{
+ unique_ptr() = default;
+ explicit unique_ptr(T* p)
+ : p(p)
+ {}
+ ~unique_ptr() { if (p) delete p; }
+ unique_ptr(unique_ptr&& old)
+ : p{std::exchange(old.p, nullptr)}
+ {}
+ unique_ptr& operator =(unique_ptr&& old)
+ {
+ if (p)
+ delete p;
+ p = std::exchange(old.p, nullptr);
+ return *this;
+ }
+private:
+ T* p = nullptr;
+
+ friend struct unique_ptr<void>;
+};
+
+template<>
+struct unique_ptr<void>
+{
+ unique_ptr() = default;
+
+ ~unique_ptr()
+ {
+ if (p)
+ d(p);
+ }
+
+ unique_ptr(unique_ptr&& old)
+ : p{std::exchange(old.p, nullptr)}
+ , d{std::exchange(old.d, nullptr)}
+ {}
+
+ unique_ptr& operator =(unique_ptr&& old)
+ {
+ if (p)
+ d(p);
+ p = std::exchange(old.p, nullptr);
+ d = std::exchange(old.d, nullptr);
+ return *this;
+ }
+
+ template <typename T>
+ unique_ptr(unique_ptr<T>&& old)
+ : p{std::exchange(old.p, nullptr)}
+ , d{[](void* x) { delete (T*)x; }}
+ {}
+
+private:
+ void* p = nullptr;
+ void (*d)(void*) = nullptr;
+};
+
+struct sentry
+{
+ sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
+ ~sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
+};
+
+int main()
+{
+ unique_ptr<> s2;
+ {
+ unique_ptr<sentry> s1{new sentry};
+ s2 = std::move(s1);
+ std::cout << "~s1\n";
+ }
+ std::cout << "~s2\n";
+}
+\ No newline at end of file