This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/blenlib/BLI_implicit_sharing_ptr.hh
Sergey Sharybin d32d787f5f Clang-Format: Allow empty functions to be single-line
For example

```
OIIOOutputDriver::~OIIOOutputDriver()
{
}
```

becomes

```
OIIOOutputDriver::~OIIOOutputDriver() {}
```

Saves quite some vertical space, which is especially handy for
constructors.

Pull Request: blender/blender#105594
2023-03-29 16:50:54 +02:00

150 lines
2.5 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bli
*/
#include "BLI_implicit_sharing.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_);
}
friend bool operator==(const ImplicitSharingPtr &a, const ImplicitSharingPtr &b)
{
return a.data_ == b.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