Advertisement
anechka_ne_plach

Raawwr

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