Program Listing for File shared.hpp¶
↰ Return to documentation for file (include/util/shared.hpp)
// SPDX-FileCopyrightText: 2021 Christian Göhring <mostsig@gmail.com>
// SPDX-License-Identifier: MIT
#ifndef THAT_THIS_UTIL_SHARED_HEADER_IS_ALREADY_INCLUDED
#define THAT_THIS_UTIL_SHARED_HEADER_IS_ALREADY_INCLUDED
#include <cstddef>
#include <utility>
namespace util {
template <class T>
class shared {
public:
constexpr shared() = default;
constexpr shared(std::nullptr_t) noexcept;
shared(T* ptr) noexcept;
shared(shared&& other) noexcept;
shared(const shared& other);
~shared();
auto operator=(shared&& other) noexcept -> shared&;
auto operator=(const shared& other) -> shared&;
auto operator->() const noexcept -> T*;
auto operator*() const noexcept -> T&;
explicit operator bool() const noexcept;
auto get() const noexcept -> T*;
auto use_count() const noexcept -> std::size_t;
private:
T* ptr = nullptr;
std::size_t* ref = new std::size_t(0);
};
template <class T, class... Args>
auto make_shared(Args&&... args) -> shared<T>;
template <class T>
constexpr shared<T>::shared(std::nullptr_t) noexcept : shared() {}
template <class T>
shared<T>::shared(T* ptr) noexcept : ptr(ptr), ref(new std::size_t(1)) {}
template <class T>
shared<T>::~shared() {
(*this->ref)--;
if (*this->ref == 0) {
delete this->ptr;
delete this->ref;
}
}
template <class T>
shared<T>::shared(shared&& other) noexcept {
this->ptr = other.ptr;
this->ref = other.ref;
other.ptr = nullptr;
other.ref = nullptr;
}
template <class T>
shared<T>::shared(const shared& other) {
this->ptr = other.ptr;
this->ref = other.ref;
if (other.ptr) {
(*this->ref)++;
}
}
template <class T>
auto shared<T>::operator=(shared&& other) noexcept -> shared<T>& {
this->ptr = other.ptr;
this->ref = other.ref;
other.ptr = nullptr;
other.ref = nullptr;
return *this;
}
template <class T>
auto shared<T>::operator=(const shared& other) -> shared<T>& {
if (this != &other) {
(*this->ref)--;
if (*this->ref == 0) {
delete this->ptr;
delete this->ref;
}
this->ptr = other.ptr;
this->ref = other.ref;
if (other.ptr) {
(*this->ref)++;
}
}
return *this;
}
template <class T>
auto shared<T>::operator->() const noexcept -> T* {
return this->ptr;
}
template <class T>
auto shared<T>::operator*() const noexcept -> T& {
return *this->ptr;
}
template <class T>
shared<T>::operator bool() const noexcept {
return this->ptr != nullptr;
}
template <class T>
auto shared<T>::get() const noexcept -> T* {
return this->ptr;
}
template <class T>
auto shared<T>::use_count() const noexcept -> std::size_t {
return *this->ref;
}
template <class T, class... Args>
auto make_shared(Args&&... args) -> shared<T> {
return shared<T>(new T(std::move(args...)));
}
} // namespace util
#endif // THAT_THIS_UTIL_SHARED_HEADER_IS_ALREADY_INCLUDED