BLI: improve const handling in ImplicitSharingPtr

The constness of the `ImplicitSharingPtr` does not imply the constness of the
referenced data, because that is determined by the user count. Therefore,
`ImplicitSharingPtr` should never give a non-const pointer to the underlying data.
Instead, one always has to check the user count, before one can do a `const_cast`.

Pull Request: https://projects.blender.org/blender/blender/pulls/115652
This commit is contained in:
Jacques Lucke
2023-12-01 11:19:39 +01:00
parent fb275bc040
commit 7730ca2b9d
3 changed files with 16 additions and 32 deletions

View File

@@ -120,17 +120,17 @@ GeometryComponent &GeometrySet::get_component_for_write(GeometryComponent::Type
if (!component_ptr) {
/* If the component did not exist before, create a new one. */
component_ptr = GeometryComponent::create(component_type);
return *component_ptr;
}
if (component_ptr->is_mutable()) {
else if (component_ptr->is_mutable()) {
/* If the referenced component is already mutable, return it directly. */
component_ptr->tag_ensured_mutable();
return *component_ptr;
}
/* If the referenced component is shared, make a copy. The copy is not shared and is
* therefore mutable. */
component_ptr = GeometryComponentPtr(component_ptr->copy());
return *component_ptr;
else {
/* If the referenced component is shared, make a copy. The copy is not shared and is
* therefore mutable. */
component_ptr = GeometryComponentPtr(component_ptr->copy());
}
return const_cast<GeometryComponent &>(*component_ptr);
}
GeometryComponent *GeometrySet::get_component_ptr(GeometryComponent::Type type)

View File

@@ -20,12 +20,12 @@ namespace blender {
*/
template<typename T> class ImplicitSharingPtr {
private:
T *data_ = nullptr;
const T *data_ = nullptr;
public:
ImplicitSharingPtr() = default;
explicit ImplicitSharingPtr(T *data) : data_(data) {}
explicit ImplicitSharingPtr(const T *data) : data_(data) {}
/* Implicit conversion from nullptr. */
ImplicitSharingPtr(std::nullptr_t) : data_(nullptr) {}
@@ -69,24 +69,12 @@ template<typename T> class ImplicitSharingPtr {
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);
@@ -98,17 +86,12 @@ template<typename T> class ImplicitSharingPtr {
return data_ != nullptr;
}
T *get()
{
return data_;
}
const T *get() const
{
return data_;
}
T *release()
const T *release()
{
T *data = data_;
data_ = nullptr;
@@ -134,14 +117,14 @@ template<typename T> class ImplicitSharingPtr {
BLI_STRUCT_EQUALITY_OPERATORS_1(ImplicitSharingPtr, data_)
private:
static void add_user(T *data)
static void add_user(const T *data)
{
if (data != nullptr) {
data->add_user();
}
}
static void remove_user_and_delete_if_last(T *data)
static void remove_user_and_delete_if_last(const T *data)
{
if (data != nullptr) {
data->remove_user_and_delete_if_last();

View File

@@ -47,10 +47,11 @@ class SharedDataContainer {
}
if (data_->is_mutable()) {
data_->tag_ensured_mutable();
return data_.get();
}
data_ = data_->copy();
return data_.get();
else {
data_ = data_->copy();
}
return const_cast<ImplicitlySharedData *>(data_.get());
}
};