/* * Copyright (c) 2016 - present Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ #pragma once #include INFER_NAMESPACE_STD_BEGIN // IMPORTANT // There is specialization of unique_ptr below and it's mosly copy paste. // When changing model, remember to change it for specialization as well! template > struct unique_ptr { // use SFINAE to determine whether _Del::pointer exists class _Pointer { template static typename _Up::pointer __test(typename _Up::pointer*); template static _Tp* __test(...); typedef typename remove_reference<_Dp>::type _Del; public: typedef decltype(__test<_Del>(0)) type; }; public: typedef typename _Pointer::type pointer; typedef _Tp element_type; typedef _Dp deleter_type; pointer data; template unique_ptr(const std__unique_ptr& u) {} constexpr unique_ptr() noexcept : data(nullptr) {} constexpr unique_ptr(nullptr_t) noexcept : unique_ptr<_Tp, _Dp>() {} unique_ptr(pointer ptr) : data(ptr) {} unique_ptr(pointer ptr, typename conditional< is_reference::value, deleter_type, typename add_lvalue_reference::type>::type __d) noexcept : data(ptr) {} unique_ptr(pointer ptr, typename remove_reference::type&& __d) noexcept : data(ptr) {} unique_ptr(unique_ptr&& u) noexcept : data(u.data) { u.data = nullptr; } template ::value && is_convertible::pointer, pointer>::value && is_convertible<_Ep, deleter_type>::value && (!is_reference::value || is_same::value)>::type> unique_ptr(unique_ptr<_Up, _Ep>&& u) noexcept : data(u.data) { u.data = nullptr; } template < class _Up, typename = typename enable_if::value>::type> unique_ptr(auto_ptr<_Up>&& __p) noexcept; ~unique_ptr() { reset(); } unique_ptr& operator=(unique_ptr&& __u) noexcept { reset(__u.data); return *this; } template ::value && is_convertible::pointer, pointer>::value && is_assignable::value>::type> unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { reset(__u.data); return *this; } unique_ptr& operator=(nullptr_t) noexcept { reset(); return *this; } typename add_lvalue_reference<_Tp>::type operator*() const { return *data; } pointer operator->() const { return data; } pointer get() const { return data; } typedef typename remove_reference::type& _Dp_reference; typedef const typename remove_reference::type& _Dp_const_reference; _Dp_const_reference get_deleter() const {} _Dp_reference get_deleter() {} explicit operator bool() const { return data != nullptr; } pointer release() { return data; } void reset(pointer p = nullptr) { data = p; } void swap(unique_ptr& u) { pointer tmp = data; data = u.data; u.data = tmp; } }; template struct unique_ptr<_Tp[], _Dp> { // use SFINAE to determine whether _Del::pointer exists class _Pointer { template static typename _Up::pointer __test(typename _Up::pointer*); template static _Tp* __test(...); typedef typename remove_reference<_Dp>::type _Del; public: typedef decltype(__test<_Del>(0)) type; }; public: typedef typename _Pointer::type pointer; typedef _Tp element_type; typedef _Dp deleter_type; pointer data; constexpr unique_ptr() noexcept : data(nullptr) {} constexpr unique_ptr(nullptr_t) noexcept : data(nullptr) {} unique_ptr(pointer ptr) : data(ptr) {} unique_ptr( pointer ptr, typename conditional< is_reference::value, deleter_type, typename add_lvalue_reference::type>::type __d) : data(ptr) {} unique_ptr(pointer ptr, typename remove_reference::type&& __d) : data(ptr) {} unique_ptr(unique_ptr&& u) : data(u.data) { u.data = nullptr; } template ::value && is_convertible::pointer, pointer>::value && is_convertible<_Ep, deleter_type>::value && (!is_reference::value || is_same::value)>::type> unique_ptr(unique_ptr<_Up, _Ep>&& u) : data(u.data) { u.data = nullptr; } template < class _Up, typename = typename enable_if::value>::type> unique_ptr(auto_ptr<_Up>&& __p) noexcept; ~unique_ptr() { reset(); } unique_ptr& operator=(unique_ptr&& __u) { reset(__u.data); return *this; } template ::value && is_convertible::pointer, pointer>::value && is_assignable::value>::type> unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) { reset(__u.data); return *this; } unique_ptr& operator=(nullptr_t) { reset(); return *this; } typename add_lvalue_reference<_Tp>::type operator[](size_t i) const {} pointer get() const { return data; } typedef typename remove_reference::type& _Dp_reference; typedef const typename remove_reference::type& _Dp_const_reference; _Dp_const_reference get_deleter() const {} _Dp_reference get_deleter() {} explicit operator bool() const { return data != nullptr; } pointer release() { return data; } void reset(pointer p = nullptr) { data = p; } void swap(unique_ptr& u) { pointer tmp = data; data = u.data; u.data = tmp; } }; template inline bool operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { return __x.get() == __y.get(); } template inline bool operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { return !(__x == __y); } template inline bool operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { /*typedef typename unique_ptr<_T1, _D1>::pointer _P1; typedef typename unique_ptr<_T2, _D2>::pointer _P2; typedef typename common_type<_P1, _P2>::type _Vp; return less<_Vp>()(__x.get(), __y.get());*/ } template inline bool operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { return __y < __x; } template inline bool operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { return !(__y < __x); } template inline bool operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { return !(__x < __y); } template inline bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return !__x; } template inline bool operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) { return !__x; } template inline bool operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return static_cast(__x); } template inline bool operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { return static_cast(__x); } template inline bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { /*typedef typename unique_ptr<_T1, _D1>::pointer _P1; return less<_P1>()(__x.get(), nullptr);*/ } template inline bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { /*typedef typename unique_ptr<_T1, _D1>::pointer _P1; return less<_P1>()(nullptr, __x.get());*/ } template inline bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return nullptr < __x; } template inline bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { return __x < nullptr; } template inline bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return !(nullptr < __x); } template inline bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { return !(__x < nullptr); } template inline bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return !(__x < nullptr); } template inline bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { return !(nullptr < __x); } template struct hash> : public hash> {}; template struct _MakeUniq2 { typedef unique_ptr<_Tp> __single_object; }; template struct _MakeUniq2<_Tp[]> { typedef unique_ptr<_Tp[]> __array; }; template struct _MakeUniq2<_Tp[_Bound]> { struct __invalid_type {}; }; /// std::make_unique for single objects template inline typename _MakeUniq2<_Tp>::__single_object make_unique( _Args&&... __args) { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } /// std::make_unique for arrays of unknown bound template inline typename _MakeUniq2<_Tp>::__array make_unique(size_t __num) { return unique_ptr<_Tp>(new typename remove_extent<_Tp>::type[__num]()); } /// Disable std::make_unique for arrays of known bound template inline typename _MakeUniq2<_Tp>::__invalid_type make_unique(_Args&&...) = delete; INFER_NAMESPACE_STD_END