inheritence stuff is annoying to fix

This commit is contained in:
Pagwin 2024-12-13 20:55:06 -05:00
parent 45a0b765a4
commit 4a9fe59bb2
No known key found for this signature in database
GPG key ID: 81137023740CA260

View file

@ -1,6 +1,8 @@
#include <atomic>
#include <type_traits>
#ifndef _POWELLCS440
#include <cassert>
#include <concepts>
#include <iostream>
#define todo(msg) \
@ -9,75 +11,65 @@
namespace cs440 {
using counter = std::atomic<std::size_t>;
template <typename T> class SharedPtr;
class Key {
Key() {}
template <typename T> struct Base {
template <typename U> friend 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:
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;
}
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>);
U *ptr;
public:
Derived(Base<T> b) : Derived{*dynamic_cast<Derived<T, U> *>(&b)} {}
U &operator*() { return *ptr; }
U *operator->() { return ptr; }
virtual ~Derived() { delete this->ptr; }
};
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}} {}
Base<T> *ptr;
counter *count;
// problem?
SharedPtr() : ptr{nullptr}, count{new std::atomic<std::size_t>{0}} {}
template <typename U>
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);
}
: 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} {}
template <typename U>
SharedPtr(const SharedPtr<U> &p) : ptr{Key().get_ptr(p)} {
Key().increment(p);
this->count = Key().get_counter(p);
SharedPtr(const SharedPtr<U> &p) : ptr(Base<T>(*p.ptr)), count{p.count} {
(*count)++;
}
SharedPtr(SharedPtr &&p)
: count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} {
Key().nullify(p);
}
template <typename U>
SharedPtr(SharedPtr<U> &&p)
: count{Key().get_counter(p)}, ptr{Key().get_ptr(p)} {
Key().nullify(p);
SharedPtr(SharedPtr &&p) : ptr{p.ptr} { p.ptr = nullptr; }
template <typename U> SharedPtr(SharedPtr<U> &&p) : ptr{p.ptr} {
p.ptr = nullptr;
}
SharedPtr &operator=(const SharedPtr &ptr) {
Key().increment(ptr);
this->count = Key().get_counter(ptr);
this->ptr = Key().get_ptr(ptr);
this->ptr = ptr.ptr;
(*count)++;
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);
this->ptr = new Derived<T, U>{Base<T>(ptr.ptr)};
return *this;
}
SharedPtr &operator=(SharedPtr &&p) {
this->count = Key().get_counter(ptr);
this->ptr = Key().get_ptr(ptr);
Key().nullify(p);
ptr = p.ptr;
p.ptr = nullptr;
}
template <typename U> SharedPtr &operator=(SharedPtr<U> &&p) {
this->count = Key().get_counter(ptr);
this->ptr = Key().get_ptr(ptr);
Key().nullify(p);
ptr = p.ptr;
p.ptr = nullptr;
}
~SharedPtr() {
if (this->count == nullptr) {
@ -91,33 +83,18 @@ public:
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>
void reset() { this->ptr = nullptr; }
template <typename U> void reset(U *p) { this->ptr = new Derived<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<T> static_pointer_cast(const SharedPtr<U> &sp) {
friend SharedPtr<U> static_pointer_cast(const SharedPtr<T> &sp) {
todo("");
}
template <typename U>
friend SharedPtr<T> dynamic_pointer_cast(const SharedPtr<U> &sp) {
friend SharedPtr<U> dynamic_pointer_cast(const SharedPtr<T> &sp) {
todo("");
}
};