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
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
@ -7,65 +8,143 @@
|
|||
assert(false);
|
||||
|
||||
namespace cs440 {
|
||||
template <typename T> class SharedPtr {
|
||||
using counter = std::atomic<std::size_t>;
|
||||
template <typename T> class SharedPtr;
|
||||
class Key {
|
||||
Key() {}
|
||||
|
||||
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>
|
||||
explicit SharedPtr(U *){todo("incomplete")} SharedPtr(const SharedPtr &p) {
|
||||
todo("incomplete")
|
||||
explicit SharedPtr(U *ptr)
|
||||
: 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>
|
||||
SharedPtr(const SharedPtr<U> &p){
|
||||
todo("incomplete")} SharedPtr(SharedPtr &&p) {
|
||||
todo("asdf")
|
||||
SharedPtr(const SharedPtr<U> &p) : ptr{Key().get_ptr(p)} {
|
||||
Key().increment(p);
|
||||
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>
|
||||
SharedPtr(SharedPtr<U> &&p){todo("asdf")} SharedPtr &
|
||||
operator=(const SharedPtr &) {
|
||||
todo("")
|
||||
SharedPtr(SharedPtr<U> &&p)
|
||||
: count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} {
|
||||
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>
|
||||
SharedPtr<T> &operator=(const SharedPtr<U> &){
|
||||
todo("")} SharedPtr &operator=(SharedPtr &&p) {
|
||||
todo("")
|
||||
friend SharedPtr<T> dynamic_pointer_cast(const SharedPtr<U> &sp) {
|
||||
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>
|
||||
bool operator==(const SharedPtr<T1> &, const SharedPtr<T2> &) {
|
||||
todo("")
|
||||
bool operator==(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
|
||||
return lhs.get() == rhs.get();
|
||||
}
|
||||
template <typename T> bool operator==(const SharedPtr<T> &, std::nullptr_t) {
|
||||
todo("")
|
||||
template <typename T>
|
||||
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> &) {
|
||||
todo("")
|
||||
template <typename T>
|
||||
bool operator==(std::nullptr_t lhs, const SharedPtr<T> &rhs) {
|
||||
return lhs == rhs.get();
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
bool operator!=(const SharedPtr<T1> &, const SharedPtr<T2> &) {
|
||||
todo("")
|
||||
bool operator!=(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template <typename T> bool operator!=(const SharedPtr<T> &, std::nullptr_t) {
|
||||
todo("")
|
||||
template <typename T>
|
||||
bool operator!=(const SharedPtr<T> &lhs, std::nullptr_t rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template <typename T> bool operator!=(std::nullptr_t, const SharedPtr<T> &) {
|
||||
todo("")
|
||||
}
|
||||
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("")
|
||||
template <typename T>
|
||||
bool operator!=(std::nullptr_t lhs, const SharedPtr<T> &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
} // namespace cs440
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue