Advertisement
anechka_ne_plach

Please work

Oct 9th, 2021
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1. #pragma once
  2. #include "compressed_pair.h"
  3. #include <memory>
  4. #include <cstddef>
  5. #include <iostream>
  6. #include <string>
  7.  
  8.  // Primary template
  9. template <typename T, typename Deleter = std::default_delete<T>>
  10. class UniquePtr {
  11. public:
  12.    
  13.     // Constructors
  14.  
  15.     explicit UniquePtr(T* ptr = nullptr) {
  16.         uptr_ = CompressedPair<T*, Deleter>(ptr, Deleter());
  17.     }
  18.  
  19.     template<typename Del>
  20.     UniquePtr(T *ptr, Del&& deleter) : uptr_(CompressedPair<T*, Deleter>(ptr, std::forward<decltype(deleter)>(deleter))){
  21.     }
  22.  
  23.     UniquePtr(const UniquePtr& other) = delete;
  24.  
  25.     UniquePtr(UniquePtr&& other) noexcept {
  26.         if (uptr_.GetFirst() != other.uptr_.GetFirst()) {
  27.             std::swap(uptr_, other.uptr_);
  28.             other.uptr_.GetFirst() = nullptr;
  29.         }
  30.     }
  31.     template <typename Tp>
  32.     UniquePtr(UniquePtr<Tp>&& other) noexcept : uptr_(other.uptr_.GetFirst(), std::forward<Deleter>(other.uptr_.GetSecond())) {
  33.          other.uptr_.GetFirst() = nullptr;
  34.     }
  35.  
  36.    
  37.     // `operator=`-s
  38.  
  39.     UniquePtr& operator=(const UniquePtr& other) = delete;
  40.  
  41.     UniquePtr& operator=(UniquePtr&& other) noexcept {
  42.         if (uptr_.GetFirst() != other.uptr_.GetFirst()) {
  43.             std::swap(uptr_.GetFirst(), other.uptr_.GetFirst());
  44.             uptr_.GetSecond() = std::forward<Deleter>(other.uptr_.GetSecond());
  45.             other.uptr_.GetSecond()(other.uptr_.GetFirst());
  46.             other.uptr_.GetFirst() = nullptr;
  47.         }
  48.         return *this;
  49.     }
  50.  
  51.     UniquePtr& operator=(std::nullptr_t) {
  52.         uptr_.GetSecond()(uptr_.GetFirst());
  53.         uptr_ = CompressedPair<T*, Deleter>(nullptr, Deleter());
  54.         return *this;
  55.     }
  56.  
  57.    
  58.     // Destructor
  59.  
  60.     ~UniquePtr() {
  61.         uptr_.GetSecond()(uptr_.GetFirst());
  62.     }
  63.  
  64.    
  65.      //Modifiers
  66.  
  67.     T* Release() noexcept {
  68.         T* tmp = uptr_.GetFirst();
  69.         uptr_.GetFirst() = nullptr;
  70.         return tmp;
  71.     }
  72.  
  73.     void Reset(T* ptr = nullptr) noexcept {
  74.         T* old_ptr = uptr_.GetFirst();
  75.         uptr_.GetFirst() = ptr;
  76.         if (old_ptr) {
  77.             uptr_.GetSecond()(old_ptr);
  78.         }
  79.     }
  80.  
  81.     void Swap(UniquePtr& other) noexcept {
  82.         std::swap(uptr_, other.uptr_);
  83.     }
  84.  
  85.    
  86.      //Observers
  87.  
  88.     T* Get() const noexcept {
  89.         return uptr_.GetFirst();
  90.     }
  91.  
  92.     Deleter& GetDeleter() {
  93.         return uptr_.GetSecond();
  94.     }
  95.  
  96.     const Deleter& GetDeleter() const {
  97.         return uptr_.GetSecond();
  98.     }
  99.  
  100.     explicit operator bool() const {
  101.         return uptr_.GetFirst() != nullptr;
  102.     }
  103.  
  104.    
  105.     // Single-object dereference operators
  106.  
  107.     typename std::add_lvalue_reference<T>::type
  108.     operator*() const {
  109.         return *Get();
  110.     }
  111.  
  112.     T* operator->() const {
  113.         return uptr_.GetFirst();
  114.     }
  115.  
  116. private:
  117.     CompressedPair<T*, Deleter> uptr_;
  118.     template<class U, class D>
  119.     friend class UniquePtr;
  120. };
  121.  
  122. // Specialization for arrays
  123. template <typename T, typename Deleter>
  124. class UniquePtr<T[], Deleter> {
  125. public:
  126.      //Constructors
  127.  
  128.     explicit UniquePtr(T* ptr = nullptr) {
  129.          uptr_ = CompressedPair<T*, Deleter>(ptr, Deleter());
  130.     }
  131.  
  132.     UniquePtr(T *ptr, Deleter deleter) {
  133.         uptr_ = CompressedPair<T*, Deleter>(ptr, deleter);
  134.     }
  135.  
  136.     UniquePtr(const UniquePtr& other) = delete;
  137.  
  138.     UniquePtr(UniquePtr&& other) noexcept {
  139.         if (uptr_.GetFirst() != other.uptr_.GetFirst()) {
  140.             uptr_ = other.uptr_;
  141.             other.uptr_.GetFirst() = nullptr;
  142.         }
  143.     }
  144.     template <typename Tp>
  145.     UniquePtr(UniquePtr<Tp>&& other) noexcept : uptr_(other.uptr_.GetFirst(), other.uptr_.GetSecond()) {
  146.         other.uptr_.GetFirst() = nullptr;
  147.     }
  148.  
  149.    
  150.    //  `operator=`-s
  151.  
  152.     UniquePtr& operator=(const UniquePtr& other) = delete;
  153.  
  154.     UniquePtr& operator=(UniquePtr&& other) noexcept {
  155.         if (uptr_.GetFirst() != other.uptr_.GetFirst()) {
  156.             std::swap(uptr_, other.uptr_);
  157.             other.uptr_.GetFirst() = nullptr;
  158.         }
  159.         return *this;
  160.     }
  161.  
  162.     UniquePtr& operator=(std::nullptr_t) {
  163.         uptr_.GetSecond()(uptr_.GetFirst());
  164.         uptr_ = CompressedPair<T*, Deleter>(nullptr, Deleter());
  165.         return *this;
  166.     }
  167.  
  168.    
  169.    //  Destructor
  170.  
  171.     ~UniquePtr() {
  172.         uptr_.GetSecond()(uptr_.GetFirst());
  173.     }
  174.  
  175.    
  176.     // Modifiers
  177.  
  178.     T* Release() noexcept {
  179.         T* tmp = uptr_.GetFirst();
  180.         uptr_.GetFirst() = nullptr;
  181.         return tmp;
  182.     }
  183.  
  184.     void Reset(T* ptr = nullptr) noexcept {
  185.         T* old_ptr = uptr_.GetFirst();
  186.         uptr_.GetFirst() = ptr;
  187.         if (old_ptr) {
  188.             uptr_.GetSecond()(old_ptr);
  189.         }
  190.     }
  191.  
  192.     void Swap(UniquePtr& other) noexcept {
  193.         std::swap(uptr_, other.uptr_);
  194.     }
  195.  
  196.     T& operator[](size_t i) {
  197.         return Get()[i];
  198.     }
  199.  
  200.    
  201.      //Observers
  202.  
  203.     T* Get() const noexcept {
  204.         return uptr_.GetFirst();
  205.     }
  206.  
  207.     Deleter& GetDeleter() {
  208.         return uptr_.GetSecond();
  209.     }
  210.  
  211.     const Deleter& GetDeleter() const {
  212.         return uptr_.GetSecond();
  213.     }
  214.  
  215.     explicit operator bool() const {
  216.         return uptr_.GetFirst() != nullptr;
  217.     }
  218.  
  219.     const T& operator[](size_t i) const {
  220.         return Get()[i];
  221.     }
  222.  
  223. private:
  224.     CompressedPair<T*, Deleter> uptr_;
  225.     template<class U, class D>
  226.     friend class UniquePtr;
  227. };
  228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement