Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <cstring>
- #include <cstdio>
- #include <set>
- #include <map>
- #include <algorithm>
- #include <vector>
- using namespace std;
- template <typename T>
- class RefCounted {
- public:
- RefCounted() {
- tCount = new int;
- *tCount = 1;
- }
- RefCounted(const RefCounted& other) : tCount(other.tCount) {
- }
- T clone(const T& val) {
- ++*tCount;
- return val;
- }
- bool release() {
- if (*tCount == 1) {
- delete tCount;
- return true;
- } else {
- --*tCount;
- return false;
- }
- }
- void Swap(RefCounted& other) {
- swap(tCount, other.tCount);
- }
- void testMethod() {
- cerr << *tCount << endl;
- }
- private:
- int* tCount;
- };
- template <typename T>
- class RefLinked {
- public:
- RefLinked() {
- }
- RefLinked(const RefLinked& other) {
- prevElement = &other;
- nextElement = other.nextElement;
- prevElement->nextElement = this;
- nextElement->prevElement = this;
- }
- T clone(const T& val) {
- return val;
- }
- bool release() {
- if (nextElement == this) {
- return true;
- }
- prevElement->nextElement = nextElement;
- nextElement->prevElement = prevElement;
- return false;
- }
- void Swap(RefLinked& other) {
- if (nextElement == this) {
- if (other.nextElement == &other) {
- return;
- }
- prevElement = other.prevElement;
- nextElement = other.nextElement;
- prevElement->nextElement = nextElement->prevElement = this;
- other.nextElement = other.prevElement = &other;
- return;
- }
- if (other.nextElement == &other) {
- other.Swap(*this);
- return;
- }
- swap(prevElement, other.prevElement);
- swap(nextElement, other.nextElement);
- swap(prevElement->nextElement, other.prevElement->nextElement);
- swap(nextElement->prevElement, other.nextElement->prevElement);
- }
- private:
- mutable const RefLinked* prevElement;
- mutable const RefLinked* nextElement;
- };
- template <typename T>
- class DestructiveCopy {
- public:
- DestructiveCopy() {
- }
- DestructiveCopy(const DestructiveCopy& ) {
- }
- T clone(T & val) {
- T result(val);
- val = T();
- return result;
- }
- bool release() {
- return true;
- }
- void Swap(DestructiveCopy&) {
- }
- };
- template <typename T>
- class NoCopy {
- public:
- NoCopy() {
- }
- bool release() {
- return true;
- }
- NoCopy(const NoCopy&);
- T clone(const T&) {
- }
- void Swap(NoCopy &) {
- }
- };
- template <typename T>
- class DefaultStorage {
- typedef T* PointerType;
- public:
- DefaultStorage() : pointer(NULL) {
- }
- DefaultStorage(const DefaultStorage& other) : pointer(other.pointer){
- }
- DefaultStorage(const PointerType &p) : pointer(p) {
- }
- PointerType operator->() const {
- return pointer;
- }
- T& operator*() const {
- return *pointer;
- }
- friend PointerType & GetRef(DefaultStorage& ds) {
- return ds.pointer;
- }
- friend const PointerType & GetRef(const DefaultStorage& ds) {
- return ds.pointer;
- }
- void Swap(DefaultStorage& other) {
- swap(pointer, other.pointer);
- }
- protected:
- void destroy() {
- delete pointer;
- }
- private:
- PointerType pointer;
- };
- template <typename T>
- class ArrayStorage {
- typedef T* PointerType;
- public:
- ArrayStorage() : pointer(NULL) {
- }
- ArrayStorage(const ArrayStorage& other) : pointer(other.pointer){
- }
- ArrayStorage(const PointerType &p) : pointer(p) {
- }
- PointerType operator->() const {
- return pointer;
- }
- T& operator*() const {
- return *pointer;
- }
- friend PointerType & GetRef(ArrayStorage& as) {
- return as.pointer;
- }
- friend const PointerType & GetRef(const ArrayStorage& as) {
- return as.pointer;
- }
- void Swap(ArrayStorage& other) {
- swap(pointer, other.pointer);
- }
- protected:
- void destroy() {
- delete[] pointer;
- }
- private:
- PointerType pointer;
- };
- template <
- typename T,
- template <typename> class StorageStrategy = DefaultStorage,
- template <typename> class OwnershipStrategy = NoCopy
- >
- class SmartPointer :
- public StorageStrategy<T>,
- public OwnershipStrategy<T*> {
- typedef StorageStrategy<T> SS;
- typedef OwnershipStrategy<T*> OS;
- typedef T* PointerType;
- public:
- SmartPointer() {
- }
- SmartPointer(const PointerType &p) : SS(p) {
- }
- SmartPointer(const SmartPointer& other) : SS(other), OS(other) {
- GetRef(this) = OS::clone(GetRef(other));
- }
- PointerType operator->() {
- return SS::operator->();
- }
- PointerType operator->() const {
- return SS::operator->();
- }
- T& operator*() {
- return SS::operator*();
- }
- T& operator*() const {
- return SS::operator*();
- }
- SmartPointer& operator = (const SmartPointer& other) {
- SmartPointer temp(other);
- temp.Swap(*this);
- return *this;
- }
- SmartPointer& operator = (SmartPointer& other) {
- SmartPointer temp(other);
- temp.Swap(*this);
- return *this;
- }
- void Swap(SmartPointer& other) {
- SS::Swap(other);
- OS::Swap(other);
- }
- ~SmartPointer() {
- if (OS::release()) {
- SS::destroy();
- }
- }
- };
- //////////////////// Test File ////////////////////
- void test_default_no_copy () {
- SmartPointer <int, DefaultStorage, NoCopy> ptr1, ptr2;
- ptr1 = new int(123);
- //ptr2 = ptr1; //- Compile Error
- } // (123) was freed
- void test_default_reference_count () {
- SmartPointer <int, DefaultStorage, RefCounted> ptr1, ptr2;
- ptr1 = new int(123); // reference counter for (123) = 1
- ptr2 = ptr1; // reference counter for (123) = 2
- if (true) {
- SmartPointer <int, DefaultStorage, RefCounted> ptr3;
- ptr3 = new int(456); // reference counter for (456) = 1
- ptr3 = new int(789); // (456) was freed and reference counter for (789) = 1
- ptr3 = ptr1; // (789) was freed and reference counter for (123) = 3
- if (true) {
- SmartPointer <int, DefaultStorage, RefCounted> ptr4;
- ptr4 = ptr1; // reference counter for (123) = 4
- } // reference counter for (123) = 3
- } // reference counter for (123) = 2
- if (true) {
- SmartPointer <int, DefaultStorage, RefCounted> ptr5(new int(456));
- ptr1 = ptr5; // reference counter for (123) = 1
- } // (456) wasn't freed
- } // (123) and (456) were freed
- void test_default_reference_list () {
- SmartPointer <int, DefaultStorage, RefLinked> ptr1, ptr2;
- ptr1 = new int(123);
- ptr2 = ptr1;
- if (true) {
- SmartPointer <int, DefaultStorage, RefLinked> ptr3;
- ptr3 = new int(456);
- ptr3 = new int(789); // (456) was freed
- ptr3 = ptr1; // (789) was freed
- if (true) {
- SmartPointer <int, DefaultStorage, RefLinked> ptr4;
- ptr4 = ptr1;
- }
- }
- if (true) {
- SmartPointer <int, DefaultStorage, RefLinked> ptr5(new int(456));
- ptr1 = ptr5;
- }
- } // (123) and (456) was freed
- void test_default_ownership_transfer() {
- SmartPointer <int, DefaultStorage, DestructiveCopy> ptr1, ptr2;
- ptr1 = new int(123);
- // cerr << "ptr1 = " << *ptr1 << endl; => ptr1 = 123
- ptr2 = ptr1;
- // cerr << "ptr1 = " << *ptr1 << endl; Runtime Error
- // cerr << "ptr2 = " << *ptr2 << endl; => ptr2 = 123
- }
- void simple_array_test() {
- SmartPointer <int, ArrayStorage> ptr1(new int[10]);
- if (true) {
- SmartPointer <int, ArrayStorage> ptr2(ptr1), ptr3(new int[5]);
- } // memory of (new int[5]) was freed
- } // memory of (new int[10]) was freed
- int main () {
- // test_default_no_copy();
- // test_default_reference_count();
- // test_default_reference_list();
- // test_default_ownership_transfer();
- // simple_array_test();
- }
Add Comment
Please, Sign In to add comment