tornavis/source/blender/blenlib/BLI_implicit_sharing_ptr.hh

150 lines
2.5 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bli
*/
#include "BLI_implicit_sharing.hh"
#include "BLI_struct_equality_utils.hh"
namespace blender {
/**
* #ImplicitSharingPtr is a smart pointer that manages implicit sharing. It's designed to work with
* types that derive from #ImplicitSharingMixin. It is fairly similar to #std::shared_ptr but
* requires the reference count to be embedded in the data.
*/
template<typename T> class ImplicitSharingPtr {
private:
T *data_ = nullptr;
public:
ImplicitSharingPtr() = default;
ImplicitSharingPtr(T *data) : data_(data) {}
ImplicitSharingPtr(const ImplicitSharingPtr &other) : data_(other.data_)
{
this->add_user(data_);
}
ImplicitSharingPtr(ImplicitSharingPtr &&other) : data_(other.data_)
{
other.data_ = nullptr;
}
~ImplicitSharingPtr()
{
this->remove_user_and_delete_if_last(data_);
}
ImplicitSharingPtr &operator=(const ImplicitSharingPtr &other)
{
if (this == &other) {
return *this;
}
this->remove_user_and_delete_if_last(data_);
data_ = other.data_;
this->add_user(data_);
return *this;
}
ImplicitSharingPtr &operator=(ImplicitSharingPtr &&other)
{
if (this == &other) {
return *this;
}
this->remove_user_and_delete_if_last(data_);
data_ = other.data_;
other.data_ = nullptr;
return *this;
}
T *operator->()
{
BLI_assert(data_ != nullptr);
return data_;
}
const T *operator->() const
{
BLI_assert(data_ != nullptr);
return data_;
}
T &operator*()
{
BLI_assert(data_ != nullptr);
return *data_;
}
const T &operator*() const
{
BLI_assert(data_ != nullptr);
return *data_;
}
operator bool() const
{
return data_ != nullptr;
}
T *get()
{
return data_;
}
const T *get() const
{
return data_;
}
T *release()
{
T *data = data_;
data_ = nullptr;
return data;
}
void reset()
{
this->remove_user_and_delete_if_last(data_);
data_ = nullptr;
}
bool has_value() const
{
return data_ != nullptr;
}
uint64_t hash() const
{
return get_default_hash(data_);
}
BLI_STRUCT_EQUALITY_OPERATORS_1(ImplicitSharingPtr, data_)
private:
static void add_user(T *data)
{
if (data != nullptr) {
data->add_user();
}
}
static void remove_user_and_delete_if_last(T *data)
{
if (data != nullptr) {
data->remove_user_and_delete_if_last();
}
}
};
} // namespace blender