]> git.saurik.com Git - apple/xnu.git/blobdiff - libkern/os/smart_ptr.h
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / libkern / os / smart_ptr.h
diff --git a/libkern/os/smart_ptr.h b/libkern/os/smart_ptr.h
deleted file mode 100644 (file)
index 5f89c7f..0000000
+++ /dev/null
@@ -1,523 +0,0 @@
-#ifndef _OS_SMART_POINTER_H
-#define _OS_SMART_POINTER_H
-
-#include <sys/cdefs.h>
-#include <os/cpp_util.h>
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wc++11-extensions"
-
-#if __has_attribute(trivial_abi)
-# define OS_TRIVIAL_ABI __attribute__((trivial_abi))
-#else
-# error Smart pointers depend on trivial_abi attribute
-#endif
-
-#if !OS_HAS_RVALUE_REFERENCES
-# error Smart pointers depend on rvalue references
-#endif
-
-/* C++98 compatibility */
-#if !OS_HAS_NULLPTR && !defined(nullptr)
-# define nullptr NULL
-#endif
-
-#ifndef OSPTR_LOG
-# define OSPTR_LOG(x, ...) do {} while(0)
-#endif
-
-namespace os {
-static struct no_retain_t {} no_retain;
-
-template<class T, class Policy>
-class OS_TRIVIAL_ABI smart_ptr
-{
-       template<class U, class OtherPolicy> friend class smart_ptr;
-
-public:
-
-/*
- * Default constructor, creates a null pointer
- */
-       smart_ptr() : pointer(nullptr)
-       {
-               OSPTR_LOG("Default construct smart_ptr\n");
-       }
-
-#if OS_HAS_NULLPTR
-/*
- * Construction from a nullptr
- */
-       smart_ptr(os::nullptr_t) : pointer(nullptr)
-       {
-               OSPTR_LOG("Construct smart_ptr from null\n");
-       }
-#endif
-
-/*
- * Construct from a raw pointer, taking a reference to the object
- */
-       explicit smart_ptr(T *&p) : pointer(p)
-       {
-               OSPTR_LOG("Construct smart_ptr from raw %p\n", pointer);
-               if (pointer != nullptr) {
-                       _retain(pointer);
-               }
-       }
-
-/*
- * Construct from a raw pointer, without bumping the refcount
- */
-       explicit smart_ptr(T *&p, no_retain_t) : pointer(p)
-       {
-               OSPTR_LOG("Construct smart_ptr from raw %p no retain\n", pointer);
-       }
-
-/*
- * Copy constructor from the same smart_ptr type
- */
-       smart_ptr(smart_ptr const &rhs) : pointer(rhs.pointer)
-       {
-               OSPTR_LOG("Copy construct smart_ptr with %p\n", rhs.pointer);
-               if (pointer != nullptr) {
-                       _retain(pointer);
-               }
-       }
-
-#if !LIBKERN_NO_MEMBER_TEMPLATES
-/*
- * Allows copy of a smart_ptr<T> from a smart_ptr<U>
- * if U is convertible to T. For example, if T is a base class of U
- */
-       template<class U>
-       smart_ptr(smart_ptr<U, Policy> const &rhs) : pointer(rhs.get())
-       {
-               OSPTR_LOG("Copy construct smart_ptr with compatible %p\n", rhs.pointer);
-               if (pointer != nullptr) {
-                       _retain(pointer);
-               }
-       }
-#endif
-
-/*
- * Assign to an OSPointer from a raw pointer
- */
-       smart_ptr &
-       operator=(T *&rhs)
-       {
-               OSPTR_LOG("Assign smart_ptr with replacing %p with raw %p\n", pointer, rhs);
-               smart_ptr(rhs).swap(*this);
-               return *this;
-       }
-
-#if OS_HAS_NULLPTR
-/*
- * Assign to an OSPointer from a null pointer
- */
-       smart_ptr &
-       operator=(os::nullptr_t)
-       {
-               OSPTR_LOG("Assign smart_ptr to null replacing %p\n", pointer);
-               smart_ptr().swap(*this);
-               return *this;
-       }
-#endif
-
-/*
- * Assign to a smart_ptr from a smart_ptr of the same type
- */
-       smart_ptr &
-       operator=(smart_ptr &rhs)
-       {
-               OSPTR_LOG("Assign smart_ptr replacing %p with %p\n", pointer, rhs.pointer);
-               smart_ptr(rhs).swap(*this);
-               return *this;
-       }
-
-#if !LIBKERN_NO_MEMBER_TEMPLATES
-/*
- * Allows assignment of a smart_ptr<T> from a smart_ptr<U>
- * if U is convertible to T. For example, if T is a base class of U.
- */
-       template <class U>
-       smart_ptr &
-       operator=(smart_ptr<U, Policy> const &rhs)
-       {
-               OSPTR_LOG("Assign smart_ptr to compatible replacing %p with %p\n", pointer, rhs.pointer);
-               smart_ptr(rhs.get()).swap(*this);
-               return *this;
-       }
-#endif
-
-/*
- * Move support
- */
-
-#if OS_HAS_RVALUE_REFERENCES
-/*
- * Move-construct from a different smart_ptr of the same pointer type
- */
-       smart_ptr(smart_ptr &&rhs) : pointer(rhs.pointer)
-       {
-               OSPTR_LOG("Move construct smart_ptr with %p\n", rhs.pointer);
-               rhs.pointer = nullptr;
-       }
-
-/*
- * Move-construct from a raw pointer
- */
-       smart_ptr(T *&&p) : pointer(p)
-       {
-               OSPTR_LOG("Move construct smart_ptr with %p\n", pointer);
-               if (pointer != nullptr) {
-                       _retain(pointer);
-               }
-               p = nullptr;
-       }
-
-/*
- * Move-construct from a raw pointer without bumping the refcount
- */
-       smart_ptr(T *&&p, no_retain_t) : pointer(p)
-       {
-               OSPTR_LOG("Move construct smart_ptr with %p no retain\n", pointer);
-               p = nullptr;
-       }
-
-/*
- * Move-assign to a smart_ptr from a raw pointer
- */
-       smart_ptr &
-       operator=(T *&&rhs)
-       {
-               OSPTR_LOG("Move assign smart_ptr replacing %p with raw %p\n", pointer, rhs);
-               smart_ptr(os::move(rhs)).swap(*this);
-               rhs = nullptr;
-               return *this;
-       }
-
-/*
- * Move-assign from a different smart_ptr of the same type
- */
-       smart_ptr &
-       operator=(smart_ptr &&rhs)
-       {
-               OSPTR_LOG("Move assign smart_ptr replacing %p with %p\n", pointer, rhs.pointer);
-               smart_ptr(os::move(rhs)).swap(*this);
-               return *this;
-       }
-
-/*
- * Move from a different smart_ptr with a compatible pointer type
- */
-       template<class U>
-       smart_ptr(smart_ptr<U, Policy> &&rhs) : pointer(rhs.pointer)
-       {
-               OSPTR_LOG("Move construct smart_ptr with compatible %p\n", rhs.pointer);
-               rhs.pointer = nullptr;
-       }
-
-       template<class U>
-       smart_ptr &
-       operator=(smart_ptr<U, Policy> &&rhs)
-       {
-               OSPTR_LOG("Move assign smart_ptr replacing %p with compatible %p\n", pointer, rhs.pointer);
-               smart_ptr(os::move(rhs)).swap(*this);
-               return *this;
-       }
-#endif
-
-/*
- * Destructor - decreases the object's reference count
- */
-       ~smart_ptr()
-       {
-               OSPTR_LOG("Destroy smart_ptr with %p\n", pointer);
-               if (pointer) {
-                       _release(pointer);
-               }
-       }
-
-/*
- * Create a new object of type T and wrap it in a smart_ptr. The object will have
- * a reference count of 1, so destruction of the smart_ptr will result in the
- * object being freed if the smart_ptr wasn't copied first.
- */
-       static inline smart_ptr
-       alloc()
-       {
-               return smart_ptr(_alloc(), no_retain);
-       }
-
-       void
-       reset()
-       {
-               smart_ptr().swap(*this);
-       }
-
-       T *
-       get() const
-       {
-               return pointer;
-       }
-
-       T **
-       get_for_out_param()
-       {
-               reset();
-               return &pointer;
-       }
-
-/*
- * Take ownership of object from raw pointer
- */
-       void
-       attach(T *&p)
-       {
-               OSPTR_LOG("Attach smart_ptr with %p\n", p);
-               smart_ptr(p, no_retain).swap(*this);
-       }
-
-       void
-       attach(T *&&p)
-       {
-               OSPTR_LOG("Move attach smart_ptr with %p\n", p);
-               smart_ptr(os::move(p), no_retain).swap(*this);
-       }
-
-/* Return and drop ownership of pointer with NO release() */
-       T *
-       detach()
-       {
-               OSPTR_LOG("Detach smart_ptr with %p\n", pointer);
-               T *ret = pointer;
-               pointer = nullptr;
-               return ret;
-       }
-
-       T *
-       operator->() const
-       {
-               OSPTR_LOG("Dereference smart_ptr with %p\n", pointer);
-               return pointer;
-       }
-
-       explicit
-       operator bool() const
-       {
-               return pointer != nullptr;
-       }
-
-       inline void
-       swap(smart_ptr &p)
-       {
-               T *temp = pointer;
-               pointer = p.pointer;
-               p.pointer = temp;
-       }
-
-/* swap pointers to the same type but with different policies */
-       template<class OtherPolicy>
-       void
-       swap(smart_ptr<T, OtherPolicy> &p)
-       {
-               if (p.pointer) {
-                       _retain(p.pointer);
-               }
-               if (pointer) {
-                       smart_ptr<T, OtherPolicy>::_retain(pointer);
-               }
-
-               T *temp = pointer;
-               pointer = p.pointer;
-               p.pointer = temp;
-
-               if (p.pointer) {
-                       _release(p.pointer);
-               }
-               if (pointer) {
-                       smart_ptr<T, OtherPolicy>::_release(pointer);
-               }
-       }
-
-       template<class U>
-       smart_ptr<U, Policy>
-       const_pointer_cast() const &
-       {
-               OSPTR_LOG("const_pointer_cast smart_ptr with %p\n", pointer);
-               return smart_ptr<U, Policy>(const_cast<U *>(pointer));
-       }
-
-       template <class U>
-       smart_ptr<U, Policy>
-       const_pointer_cast() &&
-       {
-               OSPTR_LOG("const_pointer_cast move smart_ptr with %p\n", pointer);
-               U *newPointer = const_cast<U *>(detach());
-               return smart_ptr<U, Policy>(os::move(newPointer), no_retain);
-       }
-
-       template <class U>
-       smart_ptr<U, Policy>
-       static_pointer_cast() const &
-       {
-               OSPTR_LOG("static_pointer_cast smart_ptr with %p\n", pointer);
-               return smart_ptr<U, Policy>(static_cast<U *>(pointer));
-       }
-
-       template <class U>
-       smart_ptr<U, Policy>
-       static_pointer_cast() &&
-       {
-               OSPTR_LOG("static_pointer_cast move smart_ptr with %p\n", pointer);
-               return smart_ptr<U, Policy>(static_cast<U *>(detach()), no_retain);
-       }
-
-       template <class U>
-       smart_ptr<U, Policy>
-       dynamic_pointer_cast() const &
-       {
-               OSPTR_LOG("dynamic_pointer_cast smart_ptr with %p\n", pointer);
-               return smart_ptr<U, Policy>(Policy::template dyn_cast<T, U>(pointer));
-       }
-
-       template <class U>
-       smart_ptr<U, Policy>
-       dynamic_pointer_cast() &&
-       {
-               OSPTR_LOG("dynamic_pointer_cast move smart_ptr with %p\n", pointer);
-               U *newPointer = Policy::template dyn_cast<T, U>(pointer);
-
-               if (newPointer != nullptr) {
-                       detach();
-               } else {
-                       reset();
-               }
-               return smart_ptr<U, Policy>(os::move(newPointer), no_retain);
-       }
-
-private:
-       static inline void
-       _retain(T *obj)
-       {
-               OSPTR_LOG("    %s with %p\n", __FUNCTION__, obj);
-               Policy::retain(obj);
-       }
-
-       static inline void
-       _release(T *obj)
-       {
-               OSPTR_LOG("    %s with %p\n", __FUNCTION__, obj);
-               Policy::release(obj);
-       }
-
-       static inline T *
-       _alloc()
-       {
-               OSPTR_LOG("    %s\n", __FUNCTION__);
-               return Policy::template alloc<T>();
-       }
-
-       T *pointer;
-};
-
-/*
- * Comparison
- */
-
-template<class T, class Policy>
-inline bool
-operator==(smart_ptr<T, Policy> const &a, smart_ptr<T, Policy> const &b)
-{
-       return a.get() == b.get();
-}
-
-template<class T, class Policy>
-inline bool
-operator!=(smart_ptr<T, Policy> const &a, smart_ptr<T, Policy> const &b)
-{
-       return a.get() != b.get();
-}
-
-template<class A, class A_policy, class B, class B_policy>
-inline bool
-operator==(smart_ptr<A, A_policy> const &a, smart_ptr<B, B_policy> const &b)
-{
-       return a.get() == b.get();
-}
-
-template<class A, class A_policy, class B, class B_policy>
-inline bool
-operator!=(smart_ptr<A, A_policy> const &a, smart_ptr<B, B_policy> const &b)
-{
-       return a.get() != b.get();
-}
-
-/*
- * Comparison with nullptr
- */
-
-#if OS_HAS_NULLPTR
-template<class T, class Policy>
-inline bool
-operator==(smart_ptr<T, Policy> const &p, os::nullptr_t)
-{
-       return p.get() == nullptr;
-}
-
-template<class T, class Policy> inline bool
-operator==(os::nullptr_t, smart_ptr<T, Policy> const &p)
-{
-       return p.get() == nullptr;
-}
-
-template<class T, class Policy>
-inline bool
-operator!=(smart_ptr<T, Policy> const &p, os::nullptr_t)
-{
-       return p.get() != nullptr;
-}
-
-template<class T, class Policy>
-inline bool
-operator!=(os::nullptr_t, smart_ptr<T, Policy> const &p)
-{
-       return p.get() != nullptr;
-}
-#endif
-
-/*
- * Comparison with raw pointer
- */
-
-template<class T, class Policy>
-inline bool
-operator==(smart_ptr<T, Policy> const &p, const os::remove_const_t<T> *other)
-{
-       return p.get() == other;
-}
-
-template<class T, class Policy>
-inline bool
-operator==(const os::remove_const_t<T> *other, smart_ptr<T, Policy> const &p)
-{
-       return other == p.get();
-}
-
-template<class T, class Policy>
-inline bool
-operator!=(smart_ptr<T, Policy> const &p, const os::remove_const_t<T> *other)
-{
-       return p.get() != other;
-}
-
-template<class T, class Policy>
-inline bool
-operator!=(const os::remove_const_t<T> *other, smart_ptr<T, Policy> const &p)
-{
-       return other != p.get();
-}
-};
-
-#pragma clang diagnostic pop
-#endif /* _OS_SMART_POINTER_H */