wasplib: add inv management helpers
[waspsaliva.git] / src / irr_ptr.h
blob5022adb9d6fdc0f19ea418a683716f818c0bf89c
1 /*
2 Minetest
3 Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #pragma once
21 #include <type_traits>
22 #include "irrlichttypes.h"
23 #include "IReferenceCounted.h"
25 /** Shared pointer for IrrLicht objects.
27 * It should only be used for user-managed objects, i.e. those created with
28 * the @c new operator or @c create* functions, like:
29 * `irr_ptr<scene::IMeshBuffer> buf{new scene::SMeshBuffer()};`
31 * It should *never* be used for engine-managed objects, including
32 * those created with @c addTexture and similar methods.
34 template <class ReferenceCounted,
35 class = typename std::enable_if<std::is_base_of<IReferenceCounted,
36 ReferenceCounted>::value>::type>
37 class irr_ptr
39 ReferenceCounted *value = nullptr;
41 /** Drops stored pointer replacing it with the given one.
42 * @note Copy semantics: reference counter *is* increased.
44 void grab(ReferenceCounted *object)
46 if (object)
47 object->grab();
48 reset(object);
51 public:
52 irr_ptr() {}
54 irr_ptr(std::nullptr_t) noexcept {}
56 irr_ptr(const irr_ptr &b) noexcept { grab(b.get()); }
58 irr_ptr(irr_ptr &&b) noexcept { reset(b.release()); }
60 template <typename B, class = typename std::enable_if<std::is_convertible<B *,
61 ReferenceCounted *>::value>::type>
62 irr_ptr(const irr_ptr<B> &b) noexcept
64 grab(b.get());
67 template <typename B, class = typename std::enable_if<std::is_convertible<B *,
68 ReferenceCounted *>::value>::type>
69 irr_ptr(irr_ptr<B> &&b) noexcept
71 reset(b.release());
74 /** Constructs a shared pointer out of a plain one
75 * @note Move semantics: reference counter is *not* increased.
77 explicit irr_ptr(ReferenceCounted *object) noexcept { reset(object); }
79 ~irr_ptr() { reset(); }
81 irr_ptr &operator=(const irr_ptr &b) noexcept
83 grab(b.get());
84 return *this;
87 irr_ptr &operator=(irr_ptr &&b) noexcept
89 reset(b.release());
90 return *this;
93 template <typename B, class = typename std::enable_if<std::is_convertible<B *,
94 ReferenceCounted *>::value>::type>
95 irr_ptr &operator=(const irr_ptr<B> &b) noexcept
97 grab(b.get());
98 return *this;
101 template <typename B, class = typename std::enable_if<std::is_convertible<B *,
102 ReferenceCounted *>::value>::type>
103 irr_ptr &operator=(irr_ptr<B> &&b) noexcept
105 reset(b.release());
106 return *this;
109 ReferenceCounted &operator*() const noexcept { return *value; }
110 ReferenceCounted *operator->() const noexcept { return value; }
111 explicit operator ReferenceCounted *() const noexcept { return value; }
112 explicit operator bool() const noexcept { return !!value; }
114 /** Returns the stored pointer.
116 ReferenceCounted *get() const noexcept { return value; }
118 /** Returns the stored pointer, erasing it from this class.
119 * @note Move semantics: reference counter is not changed.
121 ReferenceCounted *release() noexcept
123 ReferenceCounted *object = value;
124 value = nullptr;
125 return object;
128 /** Drops stored pointer replacing it with the given one.
129 * @note Move semantics: reference counter is *not* increased.
131 void reset(ReferenceCounted *object = nullptr) noexcept
133 if (value)
134 value->drop();
135 value = object;