Guest User

Untitled

a guest
Jul 21st, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.48 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <cstring>
  4. #include <cstdio>
  5. #include <set>
  6. #include <map>
  7. #include <algorithm>
  8. #include <vector>
  9.  
  10. using namespace std;
  11.  
  12. template <typename T>
  13. class RefCounted {
  14. public:
  15.     RefCounted() {
  16.         tCount = new int;
  17.         *tCount = 1;
  18.     }
  19.  
  20.     RefCounted(const RefCounted& other) : tCount(other.tCount) {
  21.     }
  22.  
  23.     T clone(const T& val) {
  24.         ++*tCount;
  25.         return val;
  26.     }
  27.  
  28.     bool release() {
  29.         if (*tCount == 1) {
  30.             delete tCount;
  31.             return true;
  32.         } else {
  33.             --*tCount;
  34.             return false;
  35.         }
  36.     }
  37.  
  38.     void Swap(RefCounted& other) {
  39.         swap(tCount, other.tCount);
  40.     }
  41.  
  42.     void testMethod() {
  43.         cerr << *tCount << endl;
  44.     }
  45.    
  46. private:
  47.     int* tCount;
  48. };
  49.  
  50. template <typename T>
  51. class RefLinked {
  52. public:
  53.     RefLinked() {
  54.     }
  55.  
  56.     RefLinked(const RefLinked& other) {
  57.         prevElement = &other;
  58.         nextElement = other.nextElement;
  59.         prevElement->nextElement = this;
  60.         nextElement->prevElement = this;
  61.     }
  62.  
  63.     T clone(const T& val) {
  64.         return val;
  65.     }
  66.  
  67.     bool release() {
  68.         if (nextElement == this) {
  69.             return true;
  70.         }
  71.         prevElement->nextElement = nextElement;
  72.         nextElement->prevElement = prevElement;
  73.         return false;
  74.     }
  75.  
  76.     void Swap(RefLinked& other) {
  77.         if (nextElement == this) {
  78.             if (other.nextElement == &other) {
  79.                 return;
  80.             }
  81.             prevElement = other.prevElement;
  82.             nextElement = other.nextElement;
  83.             prevElement->nextElement = nextElement->prevElement = this;
  84.             other.nextElement = other.prevElement = &other;
  85.             return;
  86.         }
  87.         if (other.nextElement == &other) {
  88.             other.Swap(*this);
  89.             return;
  90.         }
  91.         swap(prevElement, other.prevElement);
  92.         swap(nextElement, other.nextElement);
  93.         swap(prevElement->nextElement, other.prevElement->nextElement);
  94.         swap(nextElement->prevElement, other.nextElement->prevElement);
  95.     }
  96. private:
  97.     mutable const RefLinked* prevElement;
  98.     mutable const RefLinked* nextElement;
  99. };
  100.  
  101. template <typename T>
  102. class DestructiveCopy {
  103. public:
  104.     DestructiveCopy() {
  105.     }
  106.  
  107.     DestructiveCopy(const DestructiveCopy& ) {
  108.     }
  109.  
  110.     T clone(T & val) {
  111.         T result(val);
  112.         val = T();
  113.         return result;
  114.     }
  115.  
  116.     bool release() {
  117.         return true;
  118.     }
  119.  
  120.     void Swap(DestructiveCopy&) {
  121.     }
  122. };
  123.  
  124. template <typename T>
  125. class NoCopy {
  126. public:
  127.     NoCopy() {
  128.     }
  129.  
  130.     bool release() {
  131.         return true;
  132.     }
  133.  
  134.     NoCopy(const NoCopy&);
  135.     T clone(const T&) {
  136.     }
  137.  
  138.     void Swap(NoCopy &) {
  139.     }
  140. };
  141.  
  142. template <typename T>
  143. class DefaultStorage {
  144.     typedef T* PointerType;
  145. public:
  146.     DefaultStorage() : pointer(NULL) {
  147.     }
  148.    
  149.     DefaultStorage(const DefaultStorage& other) : pointer(other.pointer){
  150.     }
  151.  
  152.     DefaultStorage(const PointerType &p) : pointer(p) {
  153.     }
  154.  
  155.     PointerType operator->() const {
  156.         return pointer;
  157.     }
  158.  
  159.     T& operator*() const {
  160.         return *pointer;
  161.     }
  162.  
  163.     friend PointerType & GetRef(DefaultStorage& ds) {
  164.         return ds.pointer;
  165.     }
  166.  
  167.     friend const PointerType & GetRef(const DefaultStorage& ds) {
  168.         return ds.pointer;
  169.     }
  170.  
  171.     void Swap(DefaultStorage& other) {
  172.         swap(pointer, other.pointer);
  173.     }
  174.  
  175. protected:
  176.     void destroy() {
  177.         delete pointer;
  178.     }
  179.  
  180. private:
  181.     PointerType pointer;
  182. };
  183.  
  184. template <typename T>
  185. class ArrayStorage {
  186.     typedef T* PointerType;
  187. public:
  188.     ArrayStorage() : pointer(NULL) {
  189.     }
  190.    
  191.     ArrayStorage(const ArrayStorage& other) : pointer(other.pointer){
  192.     }
  193.  
  194.     ArrayStorage(const PointerType &p) : pointer(p) {
  195.     }
  196.  
  197.     PointerType operator->() const {
  198.         return pointer;
  199.     }
  200.  
  201.     T& operator*() const {
  202.         return *pointer;
  203.     }
  204.  
  205.     friend PointerType & GetRef(ArrayStorage& as) {
  206.         return as.pointer;
  207.     }
  208.  
  209.     friend const PointerType & GetRef(const ArrayStorage& as) {
  210.         return as.pointer;
  211.     }
  212.  
  213.     void Swap(ArrayStorage& other) {
  214.         swap(pointer, other.pointer);
  215.     }
  216.  
  217. protected:
  218.     void destroy() {
  219.         delete[] pointer;
  220.     }
  221.  
  222. private:
  223.     PointerType pointer;
  224. };
  225.  
  226. template <
  227.     typename T,
  228.     template <typename> class StorageStrategy = DefaultStorage,
  229.     template <typename> class OwnershipStrategy = NoCopy
  230. >
  231. class SmartPointer :
  232.     public StorageStrategy<T>,
  233.     public OwnershipStrategy<T*> {
  234.     typedef StorageStrategy<T> SS;
  235.     typedef OwnershipStrategy<T*> OS;
  236.     typedef T* PointerType;
  237. public:
  238.     SmartPointer() {
  239.     }
  240.  
  241.     SmartPointer(const PointerType &p) : SS(p) {
  242.     }
  243.  
  244.     SmartPointer(const SmartPointer& other) : SS(other), OS(other) {
  245.         GetRef(this) = OS::clone(GetRef(other));
  246.     }
  247.  
  248.     PointerType operator->() {
  249.         return SS::operator->();
  250.     }
  251.  
  252.     PointerType operator->() const {
  253.         return SS::operator->();
  254.     }
  255.  
  256.     T& operator*() {
  257.         return SS::operator*();
  258.     }
  259.  
  260.     T& operator*() const {
  261.         return SS::operator*();
  262.     }
  263.  
  264.     SmartPointer& operator = (const SmartPointer& other) {
  265.         SmartPointer temp(other);
  266.         temp.Swap(*this);
  267.         return *this;
  268.     }
  269.  
  270.     SmartPointer& operator = (SmartPointer& other) {
  271.         SmartPointer temp(other);
  272.         temp.Swap(*this);
  273.         return *this;
  274.     }
  275.  
  276.     void Swap(SmartPointer& other) {
  277.         SS::Swap(other);
  278.         OS::Swap(other);
  279.     }
  280.  
  281.     ~SmartPointer() {
  282.         if (OS::release()) {
  283.             SS::destroy();
  284.         }
  285.     }
  286. };
  287.  
  288. //////////////////// Test File ////////////////////
  289. void test_default_no_copy () {
  290.     SmartPointer <int, DefaultStorage, NoCopy> ptr1, ptr2;
  291.     ptr1 = new int(123);
  292.     //ptr2 = ptr1; //- Compile Error
  293. } // (123) was freed
  294.  
  295. void test_default_reference_count () {
  296.     SmartPointer <int, DefaultStorage, RefCounted> ptr1, ptr2;
  297.     ptr1 = new int(123); // reference counter for (123) = 1
  298.     ptr2 = ptr1; // reference counter for (123) = 2
  299.  
  300.     if (true) {
  301.         SmartPointer <int, DefaultStorage, RefCounted> ptr3;
  302.         ptr3 = new int(456); // reference counter for (456) = 1
  303.         ptr3 = new int(789); // (456) was freed and reference counter for (789) = 1
  304.         ptr3 = ptr1; // (789) was freed and reference counter for (123) = 3
  305.         if (true) {
  306.             SmartPointer <int, DefaultStorage, RefCounted> ptr4;
  307.             ptr4 = ptr1; // reference counter for (123) = 4
  308.         } // reference counter for (123) = 3
  309.     } // reference counter for (123) = 2
  310.  
  311.     if (true) {
  312.         SmartPointer <int, DefaultStorage, RefCounted> ptr5(new int(456));
  313.         ptr1 = ptr5; // reference counter for (123) = 1
  314.     } // (456) wasn't freed
  315. } // (123) and (456) were freed
  316.  
  317. void test_default_reference_list () {
  318.     SmartPointer <int, DefaultStorage, RefLinked> ptr1, ptr2;
  319.     ptr1 = new int(123);
  320.     ptr2 = ptr1;
  321.  
  322.     if (true) {
  323.         SmartPointer <int, DefaultStorage, RefLinked> ptr3;
  324.         ptr3 = new int(456);
  325.         ptr3 = new int(789); // (456) was freed
  326.         ptr3 = ptr1; // (789) was freed
  327.         if (true) {
  328.             SmartPointer <int, DefaultStorage, RefLinked> ptr4;
  329.             ptr4 = ptr1;
  330.         }
  331.     }
  332.  
  333.     if (true) {
  334.         SmartPointer <int, DefaultStorage, RefLinked> ptr5(new int(456));
  335.         ptr1 = ptr5;
  336.     }
  337. } // (123) and (456) was freed
  338.  
  339. void test_default_ownership_transfer() {
  340.     SmartPointer <int, DefaultStorage, DestructiveCopy> ptr1, ptr2;
  341.     ptr1 = new int(123);
  342.     // cerr << "ptr1 = " << *ptr1 << endl; => ptr1 = 123
  343.     ptr2 = ptr1;
  344.     // cerr << "ptr1 = " << *ptr1 << endl; Runtime Error
  345.     // cerr << "ptr2 = " << *ptr2 << endl; => ptr2 = 123
  346. }
  347.  
  348. void simple_array_test() {
  349.     SmartPointer <int, ArrayStorage> ptr1(new int[10]);
  350.    
  351.     if (true) {
  352.         SmartPointer <int, ArrayStorage> ptr2(ptr1), ptr3(new int[5]);
  353.     } // memory of (new int[5]) was freed
  354. } // memory of (new int[10]) was freed
  355.  
  356. int main () {
  357.  //   test_default_no_copy();
  358.  //   test_default_reference_count();
  359.  //   test_default_reference_list();
  360.  //   test_default_ownership_transfer();
  361.  
  362. //    simple_array_test();
  363. }
Add Comment
Please, Sign In to add comment