forked from Mirrorlandia_minetest/minetest
Improve irr_ptr (#10808)
This commit is contained in:
parent
ad9adcb884
commit
8dae7b47fc
@ -27,9 +27,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
* It should only be used for user-managed objects, i.e. those created with
|
* It should only be used for user-managed objects, i.e. those created with
|
||||||
* the @c new operator or @c create* functions, like:
|
* the @c new operator or @c create* functions, like:
|
||||||
* `irr_ptr<scene::IMeshBuffer> buf{new scene::SMeshBuffer()};`
|
* `irr_ptr<scene::IMeshBuffer> buf{new scene::SMeshBuffer()};`
|
||||||
|
* The reference counting is *not* balanced as new objects have reference
|
||||||
|
* count set to one, and the @c irr_ptr constructor (and @c reset) assumes
|
||||||
|
* ownership of that reference.
|
||||||
*
|
*
|
||||||
* It should *never* be used for engine-managed objects, including
|
* It shouldn’t be used for engine-managed objects, including those created
|
||||||
* those created with @c addTexture and similar methods.
|
* with @c addTexture and similar methods. Constructing @c irr_ptr directly
|
||||||
|
* from such object is a bug and may lead to a crash. Indirect construction
|
||||||
|
* is possible though; see the @c grab free function for details and use cases.
|
||||||
*/
|
*/
|
||||||
template <class ReferenceCounted,
|
template <class ReferenceCounted,
|
||||||
class = typename std::enable_if<std::is_base_of<IReferenceCounted,
|
class = typename std::enable_if<std::is_base_of<IReferenceCounted,
|
||||||
@ -38,16 +43,6 @@ class irr_ptr
|
|||||||
{
|
{
|
||||||
ReferenceCounted *value = nullptr;
|
ReferenceCounted *value = nullptr;
|
||||||
|
|
||||||
/** Drops stored pointer replacing it with the given one.
|
|
||||||
* @note Copy semantics: reference counter *is* increased.
|
|
||||||
*/
|
|
||||||
void grab(ReferenceCounted *object)
|
|
||||||
{
|
|
||||||
if (object)
|
|
||||||
object->grab();
|
|
||||||
reset(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
irr_ptr() {}
|
irr_ptr() {}
|
||||||
|
|
||||||
@ -71,8 +66,10 @@ public:
|
|||||||
reset(b.release());
|
reset(b.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs a shared pointer out of a plain one
|
/** Constructs a shared pointer out of a plain one to control object lifetime.
|
||||||
|
* @param object The object, usually returned by some @c create* function.
|
||||||
* @note Move semantics: reference counter is *not* increased.
|
* @note Move semantics: reference counter is *not* increased.
|
||||||
|
* @warning Never wrap any @c add* function with this!
|
||||||
*/
|
*/
|
||||||
explicit irr_ptr(ReferenceCounted *object) noexcept { reset(object); }
|
explicit irr_ptr(ReferenceCounted *object) noexcept { reset(object); }
|
||||||
|
|
||||||
@ -134,4 +131,70 @@ public:
|
|||||||
value->drop();
|
value->drop();
|
||||||
value = object;
|
value = object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Drops stored pointer replacing it with the given one.
|
||||||
|
* @note Copy semantics: reference counter *is* increased.
|
||||||
|
*/
|
||||||
|
void grab(ReferenceCounted *object) noexcept
|
||||||
|
{
|
||||||
|
if (object)
|
||||||
|
object->grab();
|
||||||
|
reset(object);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// ^ dislikes long lines
|
||||||
|
|
||||||
|
/** Constructs a shared pointer as a *secondary* reference to an object
|
||||||
|
*
|
||||||
|
* This function is intended to make a temporary reference to an object which
|
||||||
|
* is owned elsewhere so that it is not destroyed too early. To acheive that
|
||||||
|
* it does balanced reference counting, i.e. reference count is increased
|
||||||
|
* in this function and decreased when the returned pointer is destroyed.
|
||||||
|
*/
|
||||||
|
template <class ReferenceCounted>
|
||||||
|
irr_ptr<ReferenceCounted> grab(ReferenceCounted *object) noexcept
|
||||||
|
{
|
||||||
|
irr_ptr<ReferenceCounted> ptr;
|
||||||
|
ptr.grab(object);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceCounted>
|
||||||
|
bool operator==(const irr_ptr<ReferenceCounted> &a, const irr_ptr<ReferenceCounted> &b) noexcept
|
||||||
|
{
|
||||||
|
return a.get() == b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceCounted>
|
||||||
|
bool operator==(const irr_ptr<ReferenceCounted> &a, const ReferenceCounted *b) noexcept
|
||||||
|
{
|
||||||
|
return a.get() == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceCounted>
|
||||||
|
bool operator==(const ReferenceCounted *a, const irr_ptr<ReferenceCounted> &b) noexcept
|
||||||
|
{
|
||||||
|
return a == b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceCounted>
|
||||||
|
bool operator!=(const irr_ptr<ReferenceCounted> &a, const irr_ptr<ReferenceCounted> &b) noexcept
|
||||||
|
{
|
||||||
|
return a.get() != b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceCounted>
|
||||||
|
bool operator!=(const irr_ptr<ReferenceCounted> &a, const ReferenceCounted *b) noexcept
|
||||||
|
{
|
||||||
|
return a.get() != b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceCounted>
|
||||||
|
bool operator!=(const ReferenceCounted *a, const irr_ptr<ReferenceCounted> &b) noexcept
|
||||||
|
{
|
||||||
|
return a != b.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
Loading…
Reference in New Issue
Block a user