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
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "irrlichttypes.h"
|
||||
#include "IReferenceCounted.h"
|
||||
namespace irr { class IReferenceCounted; }
|
||||
|
||||
/** 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
|
||||
* is possible though; see the @c grab free function for details and use cases.
|
||||
*/
|
||||
template <class ReferenceCounted,
|
||||
class = typename std::enable_if<std::is_base_of<IReferenceCounted,
|
||||
ReferenceCounted>::value>::type>
|
||||
template <class ReferenceCounted>
|
||||
class irr_ptr
|
||||
{
|
||||
ReferenceCounted *value = nullptr;
|
||||
|
||||
public:
|
||||
irr_ptr() {}
|
||||
irr_ptr() noexcept = default;
|
||||
|
||||
irr_ptr(std::nullptr_t) noexcept {}
|
||||
|
||||
@ -53,15 +50,15 @@ public:
|
||||
|
||||
irr_ptr(irr_ptr &&b) noexcept { reset(b.release()); }
|
||||
|
||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
||||
ReferenceCounted *>::value>::type>
|
||||
template <typename B,
|
||||
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||
irr_ptr(const irr_ptr<B> &b) noexcept
|
||||
{
|
||||
grab(b.get());
|
||||
}
|
||||
|
||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
||||
ReferenceCounted *>::value>::type>
|
||||
template <typename B,
|
||||
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||
irr_ptr(irr_ptr<B> &&b) noexcept
|
||||
{
|
||||
reset(b.release());
|
||||
@ -88,16 +85,16 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
||||
ReferenceCounted *>::value>::type>
|
||||
template <typename B,
|
||||
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||
irr_ptr &operator=(const irr_ptr<B> &b) noexcept
|
||||
{
|
||||
grab(b.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename B, class = typename std::enable_if<std::is_convertible<B *,
|
||||
ReferenceCounted *>::value>::type>
|
||||
template <typename B,
|
||||
std::enable_if_t<std::is_convertible_v<B *, ReferenceCounted *>, bool> = true>
|
||||
irr_ptr &operator=(irr_ptr<B> &&b) noexcept
|
||||
{
|
||||
reset(b.release());
|
||||
@ -128,6 +125,8 @@ public:
|
||||
*/
|
||||
void reset(ReferenceCounted *object = nullptr) noexcept
|
||||
{
|
||||
static_assert(std::is_base_of_v<irr::IReferenceCounted, ReferenceCounted>,
|
||||
"Class is not an IReferenceCounted");
|
||||
if (value)
|
||||
value->drop();
|
||||
value = object;
|
||||
@ -138,6 +137,8 @@ public:
|
||||
*/
|
||||
void grab(ReferenceCounted *object) noexcept
|
||||
{
|
||||
static_assert(std::is_base_of_v<irr::IReferenceCounted, ReferenceCounted>,
|
||||
"Class is not an IReferenceCounted");
|
||||
if (object)
|
||||
object->grab();
|
||||
reset(object);
|
||||
@ -152,6 +153,7 @@ public:
|
||||
* in this function and decreased when the returned pointer is destroyed.
|
||||
*/
|
||||
template <class ReferenceCounted>
|
||||
[[nodiscard]]
|
||||
irr_ptr<ReferenceCounted> grab(ReferenceCounted *object) noexcept
|
||||
{
|
||||
irr_ptr<ReferenceCounted> ptr;
|
||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "exceptions.h"
|
||||
#include "irr_ptr.h"
|
||||
#include "IReferenceCounted.h"
|
||||
|
||||
class TestIrrPtr : public TestBase
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user