29#include "internal/PtrRep.h"
61 :
public std::integral_constant<
64 (!std::is_pointer<T>::value &&
67 !std::is_reference<T>::value &&
72 !std::is_const<T>::value &&
75 !std::is_volatile<T>::value &&
78 !std::is_array<T>::value)> {};
84 :
public std::integral_constant<
86 (is_compliant_base<T>::value &&
89 PointeeManager::is_copy_constructible<T>::value)> {};
207class Ptr :
private PtrInternal::PtrRep<T> {
214 using PtrRep = PtrInternal::PtrRep<T>;
225 using if_convertible_from =
226 typename std::enable_if<std::is_convertible<Y*, T*>::value>::type;
233 using if_compliant_and_convertible_from =
typename std::enable_if<
234 std::is_convertible<Y*, T*>::value &&
245 typename std::add_lvalue_reference<const element_type>::type;
286 template <class Y, class = if_compliant_and_convertible_from<Y>>
306 template <class Y, class D, class = if_compliant_and_convertible_from<Y>>
353 template <class Y, class = if_convertible_from<Y>>
378 template <class Y, class = if_convertible_from<Y>>
391 template <class Y, class = if_convertible_from<Y>>
438 template <class Y, class = if_convertible_from<Y>>
439 Ptr& operator=(
Ptr<Y> const& rhs) noexcept;
468 template <class Y, class = if_convertible_from<Y>>
481 template <class Y, class = if_convertible_from<Y>>
515 template <class Y, class = if_compliant_and_convertible_from<Y>>
532 template <class Y, class D, class = if_compliant_and_convertible_from<Y>>
588 template <typename Func>
635 explicit operator
bool() const noexcept;
676 Ptr(T* p, PtrInternal::PtrCntrlBlk* cntrlBlk,
bool doIncUseCount);
680 using PtrRep::getPointee;
695 friend struct Internal::PtrCast;
773 using if_convertible_from =
774 typename std::enable_if<std::is_convertible<Y*, T*>::value>::type;
807 template <class Y, class = if_convertible_from<Y>>
822 template <class Y, class = if_convertible_from<Y>>
829 T const& operator*() const noexcept { assert(
get());
return *
get(); }
838 T
const*
get() const noexcept {
return Base::get(); }
839 T*
get() noexcept {
return Base::getPointee(); }
845 explicit operator bool()
const {
return Base::operator bool(); }
876 Ptr<T> toImmutable() noexcept;
883 MutablePtr(T* p, PtrInternal::PtrCntrlBlk* cntrlBlk)
884 : Base(p, cntrlBlk, false) {
885 assert(Base::unique());
890 bool unique_or_null()
const {
return !*
this || Base::unique(); }
895 template <
typename Y>
898 template <
typename Y>
901 template <
typename Y>
962 template <
typename Y>
963 using if_convertible_from =
964 typename std::enable_if<std::is_convertible<Y*, T*>::value>::type;
980 template <
class Y,
class = if_convertible_from<Y>>
1008 T& operator*() {
return *m_ptr; }
1029template <
typename T>
1031template <
typename T>
1047inline constexpr Ptr<T>::Ptr(std::nullptr_t) noexcept : PtrRep(
nullptr) {}
1052template <
class Y,
class>
1056 using NonConstY =
typename std::remove_cv<Y>::type;
1057 auto nonConstP =
const_cast<NonConstY*
>(p);
1058 this->
template init_dispatch<NonConstY>(nonConstP);
1066template <
class Y,
class D,
class>
1070 this->init(p,
new PtrInternal::PtrCntrlBlkPtrDel<Y, D>(p, d));
1079inline Ptr<T>::Ptr(std::nullptr_t, D d) : PtrRep(PtrInternal::kUninitialized) {
1080 this->init(
nullptr,
new PtrInternal::PtrCntrlBlkPtrDel<T, D>(
nullptr, d));
1089inline Ptr<T>::Ptr(T* p, PtrInternal::PtrCntrlBlk* cntrlBlk,
bool doIncUseCount)
1090 : PtrRep(p, cntrlBlk) {
1091 if (doIncUseCount) this->incUseCount();
1099 : PtrRep(rhs.getPointee(), rhs.getCntrlBlk()) {
1100 this->incUseCount();
1106template <
class Y,
class>
1108 : PtrRep(rhs.getPointee(), rhs.getCntrlBlk()) {
1109 this->incUseCount();
1116 : PtrRep(rhs.getPointee(), rhs.getCntrlBlk()) {
1117 rhs.init(
nullptr,
nullptr);
1123template <
class Y,
class>
1125 : PtrRep(rhs.getPointee(), rhs.getCntrlBlk()) {
1126 rhs.init(
nullptr,
nullptr);
1132template <
class Y,
class>
1134 : PtrRep(rhs.getPointee(), rhs.getCntrlBlk()) {
1135 rhs.init(
nullptr,
nullptr);
1136 assert(!rhs.getPointee() || unique());
1148 this->PtrRep::operator=(rhs);
1155template <
class Y,
class>
1157 this->PtrRep::operator=(
Ptr(rhs));
1165 this->PtrRep::operator=(std::move(rhs));
1172template <
class Y,
class>
1174 this->PtrRep::operator=(
Ptr(std::move(rhs)));
1181template <
class Y,
class>
1183 this->PtrRep::operator=(
Ptr<T>(std::move(rhs)));
1198 this->operator=(
Ptr());
1204template <
class Y,
class>
1206 this->operator=(
Ptr(p));
1212template <
class Y,
class D,
class>
1214 this->operator=(
Ptr(p, d));
1221 auto p =
const_cast<element_type*
>(this->getPointee());
1226 auto cntrl = this->getCntrlBlk();
1229 this->init(
nullptr,
nullptr);
1234 auto cloned = cntrl->clonePointee(p);
1238 cloned.getCntrlBlk());
1246template <
typename Func>
1250 Ptr<T> o = std::move(*
this);
1257 *
this = std::move(o);
1266 assert(this->getPointee());
1267 return *this->getPointee();
1275 assert(this->getPointee());
1276 return this->getPointee();
1283 return this->getPointee();
1290 auto cblk = this->getCntrlBlk();
1291 return cblk ? cblk->use_count() : 0;
1298 return use_count() == 1;
1305 return this->getPointee() !=
nullptr;
1313 return (this->getCntrlBlk() < rhs.getCntrlBlk());
1322template <
typename T>
1328template <
typename T>
1330 assert(unique_or_null());
1335template <
typename T>
1336template <
class Y,
class>
1338 :
Base(std::move(rhs)) {
1339 assert(unique_or_null());
1344template <
typename T>
1346 assert(unique_or_null());
1351template <
typename T>
1352template <
class Y,
class>
1354 Base::operator=(std::move(rhs));
1355 assert(unique_or_null());
1361template <
typename T>
1368template <
typename T>
1379template <
typename T>
1381 : m_src(&src), m_ptr(src.toMutable()) {
1384template <
typename T>
1386 : m_src(&src), m_ptr(src.getPointee(), src.getCntrlBlk()) {
1387 m_src->init(
nullptr,
nullptr);
1389 assert(m_ptr.unique_or_null());
1391template <
typename T>
1392template <
class Y,
class>
1394 : m_src(&reinterpret_cast<
Ptr<T>&>(src)), m_ptr(src.toMutable()) {
1397template <
typename T>
1401 *m_src = m_ptr.toImmutable();
1421template <
class T,
class U>
1423 return x.get() == y.get();
1449template <
class T,
class U>
1458 return static_cast<bool>(x);
1465 return static_cast<bool>(y);
1484template <
class T,
class U>
1486 using VP =
typename std::common_type<T*, U*>::type;
1487 using V =
typename std::remove_pointer<VP>::type;
1489 return std::less<V const*>()(x.get(), y.get());
1496 return std::less<T const*>()(x.get(),
nullptr);
1503 return std::less<T const*>()(
nullptr, y.get());
1517template <
class T,
class U>
1526 return (
nullptr < x);
1533 return (y <
nullptr);
1547template <
class T,
class U>
1556 return !(
nullptr < x);
1563 return !(y <
nullptr);
1577template <
class T,
class U>
1586 return !(x <
nullptr);
1593 return !(
nullptr < y);
1622template <
class T,
class U>
1625 assert(x.get() != y.get() || &x == &y);
1626 return x.get() == y.get();
1648template <
class T,
class U>
1658 return static_cast<bool>(x);
1665 return static_cast<bool>(y);
1684template <
class T,
class U>
1686 using VP =
typename std::common_type<T*, U*>::type;
1687 using V =
typename std::remove_pointer<VP>::type;
1689 return std::less<V const*>()(x.get(), y.get());
1696 return std::less<T const*>()(x.get(),
nullptr);
1703 return std::less<T const*>()(
nullptr, y.get());
1717template <
class T,
class U>
1726 return (
nullptr < x);
1733 return (y <
nullptr);
1747template <
class T,
class U>
1757 return !(
nullptr < x);
1764 return !(y <
nullptr);
1778template <
class T,
class U>
1788 return !(x <
nullptr);
1795 return !(
nullptr < y);
1831template <
class T,
class U>
1833template <
class T,
class U>
1851template <
class T,
class U>
1853template <
class T,
class U>
1866template <
typename T>
1868 PtrInternal::DefaultPtrTraits::has_default_class<T>::value,
1871 return Internal::getDefaultClass<T>();
1873template <
typename T>
1874std::enable_if_t<PtrInternal::DefaultPtrTraits::is_array<T>::value, Ptr<T>>
1876 return Ptr<T>(PointeeManager::newClass<T>());
1878template <
typename T>
1880 !PtrInternal::DefaultPtrTraits::is_defaultable<T>::value,
1886 PtrInternal::DefaultPtrTraits::has_default_class<T>::value,
1887 "Missing default class getter for class T. See "
1888 "AMINO_DECLARE_DEFAULT_CLASS in <Amino/Cpp/ClassDeclare.h> and "
1889 "AMINO_DEFINE_DEFAULT_CLASS in <Amino/Cpp/ClassDefine.h>");
1912template <
class T,
class... Args>
1916 "The class of type T cannot be stored in an Amino::Ptr<T>");
1917 return Ptr<T>(PointeeManager::newClass<T>(std::forward<Args>(args)...));
1939template <
class T,
class E>
1943 "The class of type T cannot be stored in an Amino::Ptr<T>");
1944 return Ptr<T>(PointeeManager::newClass<T>(std::move(list)));
1961template <
class T,
class... Args>
1965 "The class of type T cannot be stored in an Amino::MutablePtr<T>");
1967 PointeeManager::newClass<T>(std::forward<Args>(args)...));
1989template <
class T,
class E>
1993 "The class of type T cannot be stored in an Amino::MutablePtr<T>");
1994 return MutablePtr<T>(PointeeManager::newClass<T>(std::move(list)));
2001template <
typename T>
2005template <
typename T1,
typename T2>
2009template <
typename T>
2021 template <
class T,
class U>
2023 T* p =
static_cast<T*
>(ptr.getPointee());
2024 return Ptr<T>(p, ptr.getCntrlBlk(),
true);
2026 template <
class T,
class U>
2028 T* p =
static_cast<T*
>(ptr.getPointee());
2029 auto ret = Ptr<T>(p, ptr.getCntrlBlk(),
false);
2030 ptr.init(
nullptr,
nullptr);
2033 template <
class T,
class U>
2035 T* p =
dynamic_cast<T*
>(ptr.getPointee());
2036 if (!p)
return Ptr<T>{};
2037 return Ptr<T>(p, ptr.getCntrlBlk(),
true);
2039 template <
class T,
class U>
2041 T* p =
dynamic_cast<T*
>(ptr.getPointee());
2046 auto ret = Ptr<T>(p, ptr.getCntrlBlk(),
false);
2047 ptr.init(
nullptr,
nullptr);
2055template <
class T,
class U>
2057 return Internal::PtrCast::static_pointer_cast<T>(ptr);
2059template <
class T,
class U>
2061 return Internal::PtrCast::static_pointer_cast<T>(std::move(ptr));
2066template <
class T,
class U>
2068 return Internal::PtrCast::dynamic_pointer_cast<T>(ptr);
2070template <
class T,
class U>
2072 return Internal::PtrCast::dynamic_pointer_cast<T>(std::move(ptr));
2096 return hash<T const*>()(ptr.get());
Amino::Ptr's forward declarations.
Ptr< T > newClassPtr(Args &&... args)
Creates a Ptr holding a new T constructed from the given arguments.
Ptr(MutablePtr< T >) -> Ptr< T >
Deduction guide for Ptr.
bool operator<(Ptr< T > const &x, Ptr< U > const &y) noexcept
Compares the pointer values.
Ptr< T > dynamic_pointer_cast(Ptr< U > const &ptr) noexcept
Dynamic pointer cast.
PtrGuard< T > createPtrGuard(Ptr< T > &src)
Create a PtrGuard for the given Ptr.
bool operator>(Ptr< T > const &x, Ptr< U > const &y) noexcept
Compares the pointer values.
void swap(MutablePtr< T > &lhs, MutablePtr< T > &rhs) noexcept
Swap two pointers.
Ptr< T > static_pointer_cast(Ptr< U > const &ptr) noexcept
Static pointer cast.
bool operator==(Ptr< T > const &x, Ptr< U > const &y) noexcept
Return true if pointers are equal.
std::enable_if_t< PtrInternal::DefaultPtrTraits::has_default_class< T >::value, Ptr< T > > makeDefaultPtr()
Creates a Ptr holding the default value for T.
bool operator<=(Ptr< T > const &x, Ptr< U > const &y) noexcept
Compares the pointer values.
void swap(Any &lhs, Any &rhs) noexcept
Swap the payloads of two instances of Any.
bool operator!=(Ptr< T > const &x, Ptr< U > const &y) noexcept
Return true if pointers are not equal.
bool operator>=(Ptr< T > const &x, Ptr< U > const &y) noexcept
Compares the pointer values.
MutablePtr< T > newMutablePtr(Args &&... args)
Creates a MutablePtr holding a new T constructed from the given arguments.
Define a Amino array of elements of type T.
Traits about the to-be-pointee of an Amino::Ptr<T> or Amino::MutablePtr<T> class.
PtrInternal::DefaultPtrTraits::is_defaultable< T > is_defaultable
Whether Ptr{PtrDefaultFlag{}} or Amino::makeDefaultPtr<T>() can be used for a pointee of type T.
Whether a Ptr<T> or MutablePtr<T> can be instantiated.
Whether the class of type T can be stored in an Amino::Ptr<T> or an Amino::MutablePtr<T>.
Flag that may be passed when creating a Ptr, to make it contain a default value as its pointee.
Smart pointers allowing custom user classes (opaque classes) to be used within Amino graphs.
void reset() noexcept
Reset the pointer to an empty pointer.
Ptr & operator=(Ptr const &rhs) noexcept
Assignment operator.
typename std::add_lvalue_reference< const element_type >::type element_const_reference_type
A reference to a const element_type.
element_type const * operator->() const noexcept
Indirection.
bool owner_before(Ptr< Y > const &rhs) const noexcept
Owner-based ordering of Ptr.
MutablePtr< element_type > toMutable() noexcept
Conversion to MutablePtr.
void swap(Ptr &rhs) noexcept
Swap two pointers.
constexpr Ptr() noexcept
Construct an empty pointer.
element_const_reference_type operator*() const noexcept
Indirection.
std::intptr_t use_count_type
The integral type of the use count.
friend class Ptr
Friendship to allow conversion between pointers of different types.
T element_type
The type of objects referenced by the Ptr pointer.
use_count_type use_count() const noexcept
Returns the use count of the pointed object.
bool unique() const noexcept
Returns whether the object is uniquely owned by the pointer.
friend class PtrGuard
Friendship to allow access to getPointee, getCtrlBlck, and init. Used when the guard is created with ...
element_type const * get() const noexcept
Accessor.
Transient version of Amino::Ptr<T> which allows mutable access to the pointee.
MutablePtr & operator=(MutablePtr &&) noexcept=default
Move assignment.
void reset()
Reset the pointer to an empty pointer.
Ptr< T > toImmutable() noexcept
Conversion to a Ptr (immutable)
T const * operator->() const noexcept
Indirection.
void swap(MutablePtr &rhs) noexcept
Swap two pointers.
constexpr MutablePtr() noexcept=default
Construct an empty MutablePtr.
T const * get() const noexcept
Accessor.
T * operator->() noexcept
Indirection.
T * get() noexcept
Indirection.
T & operator*() noexcept
Indirection.
Flag that may be passed when creating a PtrGuard.
Helper guard to allow mutation on a pointee for the lifescope of the PtrGuard<T> but then reassigning...
const T * operator->() const
Returns a const pointer to the uniquely owned object.
const T & operator*() const
Returns a const reference to the uniquely owned object.
T * operator->()
Returns a pointer to the uniquely owned object.
PtrGuard(PtrGuard &&) noexcept=default
Move constructor.
PtrGuard(Ptr< T > &src)
Constructor.
result_type operator()(const argument_type &ptr) const noexcept