examples

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

type-erased-unique_ptr.cpp (1511B)


      1 #include <utility>
      2 #include <iostream>
      3 
      4 template <typename T = void>
      5 struct unique_ptr
      6 {
      7     unique_ptr() = default;
      8     explicit unique_ptr(T* p)
      9     :   p(p)
     10     {}
     11     ~unique_ptr() { if (p) delete p; }
     12     unique_ptr(unique_ptr&& old)
     13     :   p{std::exchange(old.p, nullptr)}
     14     {}
     15     unique_ptr& operator =(unique_ptr&& old)
     16     {
     17         if (p)
     18             delete p;
     19         p = std::exchange(old.p, nullptr);
     20         return *this;
     21     }
     22 private:
     23     T* p = nullptr;
     24 
     25     friend struct unique_ptr<void>;
     26 };
     27 
     28 template<>
     29 struct unique_ptr<void>
     30 {
     31     unique_ptr() = default;
     32 
     33     ~unique_ptr()
     34     {
     35         if (p)
     36             d(p);
     37     }
     38 
     39     unique_ptr(unique_ptr&& old)
     40     :   p{std::exchange(old.p, nullptr)}
     41     ,   d{std::exchange(old.d, nullptr)}
     42     {}
     43 
     44     unique_ptr& operator =(unique_ptr&& old)
     45     {
     46         if (p)
     47             d(p);
     48         p = std::exchange(old.p, nullptr);
     49         d = std::exchange(old.d, nullptr);
     50         return *this;
     51     }
     52 
     53     template <typename T>
     54     unique_ptr(unique_ptr<T>&& old)
     55     :   p{std::exchange(old.p, nullptr)}
     56     ,   d{[](void* x) { delete (T*)x; }}
     57     {}
     58 
     59 private:
     60     void* p = nullptr;
     61     void (*d)(void*) = nullptr;
     62 };
     63 
     64 struct sentry
     65 {
     66     sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
     67     ~sentry() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
     68 };
     69 
     70 int main()
     71 {
     72     unique_ptr<> s2;
     73     {
     74         unique_ptr<sentry> s1{new sentry};
     75         s2 = std::move(s1);
     76         std::cout << "~s1\n";
     77     }
     78     std::cout << "~s2\n";
     79 }