Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.91 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <memory>
  4. #include "Test.hpp"
  5.  
  6. namespace smart_pointer {
  7.     // `exception` class definition
  8.     class exception : std::exception {
  9.         using base_class = std::exception;
  10.         using base_class::base_class;
  11.     };
  12.  
  13.     // `SmartPointer` class declaration
  14.     template <typename T, typename Allocator>
  15.     class SmartPointer {
  16.         // don't remove this macro
  17.         ENABLE_CLASS_TESTS;
  18.  
  19.     public:
  20.         using value_type = T;
  21.  
  22.         // constructor
  23.         explicit SmartPointer(value_type* p = nullptr){
  24.             if (p == nullptr) core = nullptr;
  25.             else {
  26.                 core = &Core(p);
  27.                 core->AddRef();
  28.             }
  29.         }
  30.  
  31.         // copy constructor
  32.         SmartPointer(const SmartPointer& optr) : core(optr.core) { core->AddRef(); }
  33.  
  34.         // move constructor
  35.         SmartPointer(SmartPointer&&) = default;
  36.  
  37.         // copy assigment
  38.         SmartPointer& operator=(const SmartPointer&) = default;
  39.  
  40.         // move assigment
  41.         SmartPointer& operator=(SmartPointer&& sp) {
  42.             if (this != &sp) {
  43.                 if (core->Release() == 0) {
  44.                     delete core;
  45.                 }
  46.  
  47.                 core = sp.core;
  48.                 core->AddRef();
  49.             }
  50.             return *this;
  51.         }
  52.  
  53.         //
  54.         SmartPointer& operator=(value_type* other) {
  55.             core->p = other;
  56.             core->AddRef();
  57.             return *this;
  58.         }
  59.  
  60.         ~SmartPointer() {
  61.             if (core->Release() == 0) delete core;
  62.         }
  63.  
  64.         // return reference to the object of class/type T
  65.         // if SmartPointer contains nullptr throw `SmartPointer::exception`
  66.         value_type& operator*() {
  67.             if (core->p == nullptr) throw exception();
  68.             return *core->p;
  69.         }
  70.  
  71.         const value_type& operator*() const {
  72.             if (core->p == nullptr) throw exception();
  73.             auto const f = *core->p;
  74.             return f;
  75.         }
  76.  
  77.         // return pointer to the object of class/type T
  78.         value_type* operator->() const { return core->p; }
  79.  
  80.         value_type* get() const { return core->p; }
  81.  
  82.         // if pointer == nullptr => return false
  83.         operator bool() const { return core->p != nullptr; }
  84.  
  85.         // if pointers points to the same address or both null => true
  86.         template <typename U, typename AnotherAllocator>
  87.         bool operator==(const SmartPointer<U, AnotherAllocator>& pp) const {
  88.             return static_cast<void*>(core->p) == static_cast<void*>(pp.core->p);
  89.         }
  90.  
  91.         // if pointers points to the same address or both null => false
  92.         template <typename U, typename AnotherAllocator>
  93.         bool operator!=(const SmartPointer<U, AnotherAllocator>& other) const {
  94.             return static_cast<void*>(other.core->p) != static_cast<void*>(core->p);
  95.         }
  96.  
  97.         // if smart pointer contains non-nullptr => return count owners
  98.         // if smart pointer contains nullptr => return 0
  99.         std::size_t count_owners() const {
  100.             if (core->p == nullptr) return 0;
  101.             return core->c;
  102.         }
  103.  
  104.     public:
  105.         class Core {
  106.         public:
  107.             value_type* p;
  108.             size_t c;
  109.  
  110.             explicit Core(value_type* _p = nullptr) : p(_p), c(0) {}
  111.  
  112.             void AddRef() { ++c; }
  113.  
  114.             int Release() { return --c; }
  115.  
  116.             ~Core() {
  117.                 if (p != nullptr) delete p;
  118.             }
  119.         };
  120.         Core* core;
  121.     };
  122. }  // namespace smart_pointer
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement