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:
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user