more inheritence fuckery
This commit is contained in:
parent
4a9fe59bb2
commit
d90f19f897
1 changed files with 19 additions and 19 deletions
|
@ -17,22 +17,20 @@ template <typename T> struct Base {
|
||||||
T *ptr;
|
T *ptr;
|
||||||
Base(T *ptr) : ptr{ptr} {}
|
Base(T *ptr) : ptr{ptr} {}
|
||||||
template <typename U> Base(Base<U> const &ptr) : ptr{ptr.ptr} {}
|
template <typename U> Base(Base<U> const &ptr) : ptr{ptr.ptr} {}
|
||||||
template <typename U> operator U() { return U(*this); }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual T &operator*() { return *ptr; }
|
virtual T &operator*() { return *ptr; }
|
||||||
virtual T *operator->() { return ptr; }
|
virtual T *operator->() { return ptr; }
|
||||||
virtual ~Base() = default;
|
virtual ~Base() = default;
|
||||||
};
|
};
|
||||||
template <typename T, typename U> class Derived : public Base<T> {
|
template <typename T, typename U> class MyDerived : public Base<T> {
|
||||||
static_assert(std::is_base_of_v<T, U>);
|
|
||||||
U *ptr;
|
U *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Derived(Base<T> b) : Derived{*dynamic_cast<Derived<T, U> *>(&b)} {}
|
MyDerived(U *ptr) : Base<T>{ptr} { this->ptr = ptr; }
|
||||||
U &operator*() { return *ptr; }
|
U &operator*() { return *ptr; }
|
||||||
U *operator->() { return ptr; }
|
U *operator->() { return ptr; }
|
||||||
virtual ~Derived() { delete this->ptr; }
|
virtual ~MyDerived() { delete this->ptr; }
|
||||||
};
|
};
|
||||||
template <typename T> class SharedPtr {
|
template <typename T> class SharedPtr {
|
||||||
public:
|
public:
|
||||||
|
@ -43,11 +41,12 @@ public:
|
||||||
SharedPtr() : ptr{nullptr}, count{new std::atomic<std::size_t>{0}} {}
|
SharedPtr() : ptr{nullptr}, count{new std::atomic<std::size_t>{0}} {}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
explicit SharedPtr(U *ptr)
|
explicit SharedPtr(U *ptr)
|
||||||
: ptr{static_cast<Base<T> *>(new Derived<T, U>{ptr})},
|
: ptr{static_cast<Base<T> *>(new MyDerived<T, U>{ptr})},
|
||||||
count{new std::atomic<std::size_t>{ptr ? 1 : 0}} {}
|
count{new std::atomic<std::size_t>{
|
||||||
SharedPtr(const SharedPtr &p) : ptr{p.ptr} {}
|
static_cast<std::size_t>(ptr ? 1 : 0)}} {}
|
||||||
|
SharedPtr(const SharedPtr &p) : ptr{p.ptr}, count{p.count} {}
|
||||||
template <typename U>
|
template <typename U>
|
||||||
SharedPtr(const SharedPtr<U> &p) : ptr(Base<T>(*p.ptr)), count{p.count} {
|
SharedPtr(const SharedPtr<U> &p) : ptr(p.ptr), count{p.count} {
|
||||||
(*count)++;
|
(*count)++;
|
||||||
}
|
}
|
||||||
SharedPtr(SharedPtr &&p) : ptr{p.ptr} { p.ptr = nullptr; }
|
SharedPtr(SharedPtr &&p) : ptr{p.ptr} { p.ptr = nullptr; }
|
||||||
|
@ -60,12 +59,13 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template <typename U> SharedPtr<T> &operator=(const SharedPtr<U> &ptr) {
|
template <typename U> SharedPtr<T> &operator=(const SharedPtr<U> &ptr) {
|
||||||
this->ptr = new Derived<T, U>{Base<T>(ptr.ptr)};
|
this->ptr = new MyDerived<T, U>{Base<T>(*ptr.ptr)};
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
SharedPtr &operator=(SharedPtr &&p) {
|
SharedPtr &operator=(SharedPtr &&p) {
|
||||||
ptr = p.ptr;
|
ptr = p.ptr;
|
||||||
p.ptr = nullptr;
|
p.ptr = nullptr;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
template <typename U> SharedPtr &operator=(SharedPtr<U> &&p) {
|
template <typename U> SharedPtr &operator=(SharedPtr<U> &&p) {
|
||||||
ptr = p.ptr;
|
ptr = p.ptr;
|
||||||
|
@ -84,20 +84,20 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void reset() { this->ptr = nullptr; }
|
void reset() { this->ptr = nullptr; }
|
||||||
template <typename U> void reset(U *p) { this->ptr = new Derived<U>{p}; }
|
template <typename U> void reset(U *p) { this->ptr = new MyDerived<T, U>{p}; }
|
||||||
T *get() const { return this->ptr->ptr; }
|
T *get() const { return this->ptr->ptr; }
|
||||||
T &operator*() const { return this->ptr->operator*(); }
|
T &operator*() const { return this->ptr->operator*(); }
|
||||||
T *operator->() const { return this->ptr->operator->(); }
|
T *operator->() const { return this->ptr->operator->(); }
|
||||||
explicit operator bool() const { return this->ptr->ptr != nullptr; }
|
explicit operator bool() const { return this->ptr->ptr != nullptr; }
|
||||||
template <typename U>
|
|
||||||
friend SharedPtr<U> static_pointer_cast(const SharedPtr<T> &sp) {
|
|
||||||
todo("");
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
friend SharedPtr<U> dynamic_pointer_cast(const SharedPtr<T> &sp) {
|
|
||||||
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 T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
bool operator==(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
|
bool operator==(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
|
||||||
return lhs.get() == rhs.get();
|
return lhs.get() == rhs.get();
|
||||||
|
|
Loading…
Reference in a new issue