mirror of
https://github.com/minetest/minetest.git
synced 2024-12-22 14:12:24 +01:00
irr_ptr: Allow to use with forward-declared types
Also add [[nodiscard]] to ::grab() (because similar named irr_ptr::grab() returns void). And use new std::is_convertible_v.
This commit is contained in:
parent
70e169f165
commit
6d01ed5d74
@ -20,8 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "irrlichttypes.h"
|
namespace irr { class IReferenceCounted; }
|
||||||
#include "IReferenceCounted.h"
|
|
||||||
|
|
||||||
/** Shared pointer for IrrLicht objects.
|
/** Shared pointer for IrrLicht objects.
|
||||||
*
|
*
|
||||||
@ -37,15 +36,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
* from such object is a bug and may lead to a crash. Indirect construction
|
* 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.
|
* 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,
|
|
||||||
ReferenceCounted>::value>::type>
|
|
||||||
class irr_ptr
|
class irr_ptr
|
||||||
{
|
{
|
||||||
ReferenceCounted *value = nullptr;
|
ReferenceCounted *value = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
irr_ptr() {}
|
irr_ptr() noexcept = default;
|
||||||
|
|
||||||
irr_ptr(std::nullptr_t) noexcept {}
|
irr_ptr(std::nullptr_t) noexcept {}
|
||||||
|
|
||||||
@ -53,15 +50,15 @@ public:
|
|||||||
|
|
||||||
irr_ptr(irr_ptr &&b) noexcept { reset(b.release()); }
|
irr_ptr(irr_ptr &&b) noexcept { reset(b.release()); }
|
||||||
|
|
||||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
template <typename B,
|
||||||
ReferenceCounted *>::value>::type>
|
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||||
irr_ptr(const irr_ptr<B> &b) noexcept
|
irr_ptr(const irr_ptr<B> &b) noexcept
|
||||||
{
|
{
|
||||||
grab(b.get());
|
grab(b.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
template <typename B,
|
||||||
ReferenceCounted *>::value>::type>
|
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||||
irr_ptr(irr_ptr<B> &&b) noexcept
|
irr_ptr(irr_ptr<B> &&b) noexcept
|
||||||
{
|
{
|
||||||
reset(b.release());
|
reset(b.release());
|
||||||
@ -88,16 +85,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
template <typename B,
|
||||||
ReferenceCounted *>::value>::type>
|
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||||
irr_ptr &operator=(const irr_ptr<B> &b) noexcept
|
irr_ptr &operator=(const irr_ptr<B> &b) noexcept
|
||||||
{
|
{
|
||||||
grab(b.get());
|
grab(b.get());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
template <typename B,
|
||||||
ReferenceCounted *>::value>::type>
|
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||||
irr_ptr &operator=(irr_ptr<B> &&b) noexcept
|
irr_ptr &operator=(irr_ptr<B> &&b) noexcept
|
||||||
{
|
{
|
||||||
reset(b.release());
|
reset(b.release());
|
||||||
@ -128,6 +125,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void reset(ReferenceCounted *object = nullptr) noexcept
|
void reset(ReferenceCounted *object = nullptr) noexcept
|
||||||
{
|
{
|
||||||
|
static_assert(std::is_base_of_v<irr::IReferenceCounted, ReferenceCounted>,
|
||||||
|
"Class is not an IReferenceCounted");
|
||||||
if (value)
|
if (value)
|
||||||
value->drop();
|
value->drop();
|
||||||
value = object;
|
value = object;
|
||||||
@ -138,6 +137,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void grab(ReferenceCounted *object) noexcept
|
void grab(ReferenceCounted *object) noexcept
|
||||||
{
|
{
|
||||||
|
static_assert(std::is_base_of_v<irr::IReferenceCounted, ReferenceCounted>,
|
||||||
|
"Class is not an IReferenceCounted");
|
||||||
if (object)
|
if (object)
|
||||||
object->grab();
|
object->grab();
|
||||||
reset(object);
|
reset(object);
|
||||||
@ -152,6 +153,7 @@ public:
|
|||||||
* in this function and decreased when the returned pointer is destroyed.
|
* in this function and decreased when the returned pointer is destroyed.
|
||||||
*/
|
*/
|
||||||
template <class ReferenceCounted>
|
template <class ReferenceCounted>
|
||||||
|
[[nodiscard]]
|
||||||
irr_ptr<ReferenceCounted> grab(ReferenceCounted *object) noexcept
|
irr_ptr<ReferenceCounted> grab(ReferenceCounted *object) noexcept
|
||||||
{
|
{
|
||||||
irr_ptr<ReferenceCounted> ptr;
|
irr_ptr<ReferenceCounted> ptr;
|
||||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "irr_ptr.h"
|
#include "irr_ptr.h"
|
||||||
|
#include "IReferenceCounted.h"
|
||||||
|
|
||||||
class TestIrrPtr : public TestBase
|
class TestIrrPtr : public TestBase
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user