more inheritence fuckery

This commit is contained in:
Pagwin 2024-12-13 22:23:04 -05:00
parent 4a9fe59bb2
commit d90f19f897
No known key found for this signature in database
GPG key ID: 81137023740CA260

View file

@ -17,22 +17,20 @@ template <typename T> struct Base {
T *ptr;
Base(T *ptr) : ptr{ptr} {}
template <typename U> Base(Base<U> const &ptr) : ptr{ptr.ptr} {}
template <typename U> operator U() { return U(*this); }
public:
virtual T &operator*() { return *ptr; }
virtual T *operator->() { return ptr; }
virtual ~Base() = default;
};
template <typename T, typename U> class Derived : public Base<T> {
static_assert(std::is_base_of_v<T, U>);
template <typename T, typename U> class MyDerived : public Base<T> {
U *ptr;
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; }
virtual ~Derived() { delete this->ptr; }
virtual ~MyDerived() { delete this->ptr; }
};
template <typename T> class SharedPtr {
public:
@ -43,11 +41,12 @@ public:
SharedPtr() : ptr{nullptr}, count{new std::atomic<std::size_t>{0}} {}
template <typename U>
explicit SharedPtr(U *ptr)
: ptr{static_cast<Base<T> *>(new Derived<T, U>{ptr})},
count{new std::atomic<std::size_t>{ptr ? 1 : 0}} {}
SharedPtr(const SharedPtr &p) : ptr{p.ptr} {}
: ptr{static_cast<Base<T> *>(new MyDerived<T, U>{ptr})},
count{new std::atomic<std::size_t>{
static_cast<std::size_t>(ptr ? 1 : 0)}} {}
SharedPtr(const SharedPtr &p) : ptr{p.ptr}, count{p.count} {}
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)++;
}
SharedPtr(SharedPtr &&p) : ptr{p.ptr} { p.ptr = nullptr; }
@ -60,12 +59,13 @@ public:
return *this;
}
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;
}
SharedPtr &operator=(SharedPtr &&p) {
ptr = p.ptr;
p.ptr = nullptr;
return *this;
}
template <typename U> SharedPtr &operator=(SharedPtr<U> &&p) {
ptr = p.ptr;
@ -84,20 +84,20 @@ public:
}
}
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 &operator*() const { return this->ptr->operator*(); }
T *operator->() const { return this->ptr->operator->(); }
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>
bool operator==(const SharedPtr<T1> &lhs, const SharedPtr<T2> &rhs) {
return lhs.get() == rhs.get();