remaining issues are private/protected destructors and the pointer casts
This commit is contained in:
parent
cacc07d01c
commit
45a0b765a4
1 changed files with 121 additions and 42 deletions
163
SharedPtr.hpp
163
SharedPtr.hpp
|
@ -1,3 +1,4 @@
|
||||||
|
#include <atomic>
|
||||||
#ifndef _POWELLCS440
|
#ifndef _POWELLCS440
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -7,65 +8,143 @@
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
namespace cs440 {
|
namespace cs440 {
|
||||||
template <typename T> class SharedPtr {
|
using counter = std::atomic<std::size_t>;
|
||||||
|
template <typename T> class SharedPtr;
|
||||||
|
class Key {
|
||||||
|
Key() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SharedPtr() { todo("incomplete") }
|
template <typename U> friend class SharedPtr;
|
||||||
|
template <typename U> void increment(SharedPtr<U> const &ptr) {
|
||||||
|
const_cast<std::atomic<size_t> &>(*ptr.count)++;
|
||||||
|
}
|
||||||
|
template <typename U> counter *get_counter(SharedPtr<U> const &ptr) {
|
||||||
|
return const_cast<std::atomic<size_t> *>(ptr.count);
|
||||||
|
}
|
||||||
|
template <typename U> U *get_ptr(SharedPtr<U> const &ptr) {
|
||||||
|
return const_cast<U *>(ptr.ptr);
|
||||||
|
}
|
||||||
|
template <typename U> void nullify(SharedPtr<U> &&ptr) {
|
||||||
|
ptr.ptr = nullptr;
|
||||||
|
ptr.count = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename T> class SharedPtr {
|
||||||
|
T *ptr;
|
||||||
|
std::atomic<std::size_t> *count;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class Key;
|
||||||
|
SharedPtr() : ptr{nullptr}, count{new std::atomic<std::size_t>{1}} {}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
explicit SharedPtr(U *){todo("incomplete")} SharedPtr(const SharedPtr &p) {
|
explicit SharedPtr(U *ptr)
|
||||||
todo("incomplete")
|
: ptr{ptr}, count{new std::atomic<std::size_t>{1}} {}
|
||||||
|
SharedPtr(const SharedPtr &p) : ptr{p.ptr} {
|
||||||
|
Key().increment(p);
|
||||||
|
this->count = Key().get_counter(p);
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
SharedPtr(const SharedPtr<U> &p){
|
SharedPtr(const SharedPtr<U> &p) : ptr{Key().get_ptr(p)} {
|
||||||
todo("incomplete")} SharedPtr(SharedPtr &&p) {
|
Key().increment(p);
|
||||||
todo("asdf")
|
this->count = Key().get_counter(p);
|
||||||
|
}
|
||||||
|
SharedPtr(SharedPtr &&p)
|
||||||
|
: count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} {
|
||||||
|
Key().nullify(p);
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
SharedPtr(SharedPtr<U> &&p){todo("asdf")} SharedPtr &
|
SharedPtr(SharedPtr<U> &&p)
|
||||||
operator=(const SharedPtr &) {
|
: count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} {
|
||||||
todo("")
|
Key().nullify(p);
|
||||||
|
}
|
||||||
|
SharedPtr &operator=(const SharedPtr &ptr) {
|
||||||
|
Key().increment(ptr);
|
||||||
|
this->count = Key().get_counter(ptr);
|
||||||
|
this->ptr = Key().get_ptr(ptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template <typename U> SharedPtr<T> &operator=(const SharedPtr<U> &ptr) {
|
||||||
|
Key().increment(ptr);
|
||||||
|
this->count = Key().get_counter(ptr);
|
||||||
|
this->ptr = Key().get_ptr(ptr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SharedPtr &operator=(SharedPtr &&p) {
|
||||||
|
this->count = Key().get_counter(ptr);
|
||||||
|
this->ptr = Key().get_ptr(ptr);
|
||||||
|
Key().nullify(p);
|
||||||
|
}
|
||||||
|
template <typename U> SharedPtr &operator=(SharedPtr<U> &&p) {
|
||||||
|
this->count = Key().get_counter(ptr);
|
||||||
|
this->ptr = Key().get_ptr(ptr);
|
||||||
|
Key().nullify(p);
|
||||||
|
}
|
||||||
|
~SharedPtr() {
|
||||||
|
if (this->count == nullptr) {
|
||||||
|
if (this->ptr != nullptr) {
|
||||||
|
delete this->ptr;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (--(*this->count) == 0) {
|
||||||
|
delete this->count;
|
||||||
|
delete this->ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void reset() {
|
||||||
|
if (this->count != nullptr) {
|
||||||
|
if (--(*this->count) == 0) {
|
||||||
|
delete this->count;
|
||||||
|
delete this->ptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->ptr = nullptr;
|
||||||
|
this->count = nullptr;
|
||||||
|
}
|
||||||
|
template <typename U> void reset(U *p) {
|
||||||
|
this->reset();
|
||||||
|
this->count = new counter{1};
|
||||||
|
this->ptr = p;
|
||||||
|
}
|
||||||
|
T *get() const { return this->ptr; }
|
||||||
|
T &operator*() const { return *this->ptr; }
|
||||||
|
T *operator->() const { return this->ptr; }
|
||||||
|
explicit operator bool() const { return this->ptr != nullptr; }
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
template <typename U>
|
||||||
|
friend SharedPtr<T> static_pointer_cast(const SharedPtr<U> &sp) {
|
||||||
|
todo("");
|
||||||
}
|
}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
SharedPtr<T> &operator=(const SharedPtr<U> &){
|
friend SharedPtr<T> dynamic_pointer_cast(const SharedPtr<U> &sp) {
|
||||||
todo("")} SharedPtr &operator=(SharedPtr &&p) {
|
todo("");
|
||||||
todo("")
|
|
||||||
}
|
}
|
||||||
template <typename U> SharedPtr &operator=(SharedPtr<U> &&p) { todo("") }
|
|
||||||
~SharedPtr() { todo("") }
|
|
||||||
void reset() { todo("") }
|
|
||||||
template <typename U>
|
|
||||||
void reset(U *p){todo("")} T *get() const {todo("")} T &operator*() const {
|
|
||||||
todo("")} T *operator-> () const {
|
|
||||||
todo("")
|
|
||||||
}
|
|
||||||
explicit operator bool() const { todo("") }
|
|
||||||
};
|
};
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
bool operator==(const SharedPtr<T1> &, const SharedPtr<T2> &) {
|
bool operator==(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
|
||||||
todo("")
|
return lhs.get() == rhs.get();
|
||||||
}
|
}
|
||||||
template <typename T> bool operator==(const SharedPtr<T> &, std::nullptr_t) {
|
template <typename T>
|
||||||
todo("")
|
bool operator==(const SharedPtr<T> &lhs, std::nullptr_t rhs) {
|
||||||
|
|
||||||
|
return lhs.get() == rhs;
|
||||||
}
|
}
|
||||||
template <typename T> bool operator==(std::nullptr_t, const SharedPtr<T> &) {
|
template <typename T>
|
||||||
todo("")
|
bool operator==(std::nullptr_t lhs, const SharedPtr<T> &rhs) {
|
||||||
|
return lhs == rhs.get();
|
||||||
}
|
}
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
bool operator!=(const SharedPtr<T1> &, const SharedPtr<T2> &) {
|
bool operator!=(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
|
||||||
todo("")
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
template <typename T> bool operator!=(const SharedPtr<T> &, std::nullptr_t) {
|
template <typename T>
|
||||||
todo("")
|
bool operator!=(const SharedPtr<T> &lhs, std::nullptr_t rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
template <typename T> bool operator!=(std::nullptr_t, const SharedPtr<T> &) {
|
template <typename T>
|
||||||
todo("")
|
bool operator!=(std::nullptr_t lhs, const SharedPtr<T> &rhs) {
|
||||||
}
|
return !(lhs == rhs);
|
||||||
template <typename T, typename U>
|
|
||||||
SharedPtr<T> static_pointer_cast(const SharedPtr<U> &sp) {
|
|
||||||
todo("")
|
|
||||||
}
|
|
||||||
template <typename T, typename U>
|
|
||||||
SharedPtr<T> dynamic_pointer_cast(const SharedPtr<U> &sp) {
|
|
||||||
todo("")
|
|
||||||
}
|
}
|
||||||
} // namespace cs440
|
} // namespace cs440
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue