examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

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:
Asrc/type-erased-unique_ptr.cpp | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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