}
};
- /// 20.7.1.2 unique_ptr for single objects.
- template <typename _Tp, typename _Dp = default_delete<_Tp> >
- class unique_ptr
+ template <typename _Tp, typename _Dp>
+ class __uniq_ptr_impl
{
- // use SFINAE to determine whether _Del::pointer exists
- class _Pointer
- {
- template<typename _Up>
- static typename _Up::pointer __test(typename _Up::pointer*);
+ template <typename _Up, typename _Ep, typename = void>
+ struct _Ptr
+ {
+ using type = _Up*;
+ };
+
+ template <typename _Up, typename _Ep>
+ struct
+ _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
+ {
+ using type = typename remove_reference<_Ep>::type::pointer;
+ };
- template<typename _Up>
- static _Tp* __test(...);
+ public:
+ using pointer = typename _Ptr<_Tp, _Dp>::type;
- typedef typename remove_reference<_Dp>::type _Del;
+ __uniq_ptr_impl() = default;
+ __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
- public:
- typedef decltype(__test<_Del>(0)) type;
- };
+ template<typename _Del>
+ __uniq_ptr_impl(pointer __p, _Del&& __d)
+ : _M_t(__p, std::forward<_Del>(__d)) { }
- typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
- __tuple_type _M_t;
+ pointer& _M_ptr() { return std::get<0>(_M_t); }
+ pointer _M_ptr() const { return std::get<0>(_M_t); }
+ _Dp& _M_deleter() { return std::get<1>(_M_t); }
+ const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
- public:
- typedef typename _Pointer::type pointer;
- typedef _Tp element_type;
- typedef _Dp deleter_type;
+ private:
+ tuple<pointer, _Dp> _M_t;
+ };
+
+ /// 20.7.1.2 unique_ptr for single objects.
+ template <typename _Tp, typename _Dp = default_delete<_Tp>>
+ class unique_ptr
+ {
+ __uniq_ptr_impl<_Tp, _Dp> _M_t;
+ public:
+ using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
+ using element_type = _Tp;
+ using deleter_type = _Dp;
// helper template for detecting a safe conversion from another
// unique_ptr
*/
explicit
unique_ptr(pointer __p) noexcept
- : _M_t(__p, deleter_type())
+ : _M_t(__p)
{ static_assert(!is_pointer<deleter_type>::value,
"constructed with null function pointer deleter"); }
/// Destructor, invokes the deleter if the stored pointer is not null.
~unique_ptr() noexcept
{
- auto& __ptr = std::get<0>(_M_t);
+ auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
/// Return the stored pointer.
pointer
get() const noexcept
- { return std::get<0>(_M_t); }
+ { return _M_t._M_ptr(); }
/// Return a reference to the stored deleter.
deleter_type&
get_deleter() noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return a reference to the stored deleter.
const deleter_type&
get_deleter() const noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return @c true if the stored pointer is not null.
explicit operator bool() const noexcept
release() noexcept
{
pointer __p = get();
- std::get<0>(_M_t) = pointer();
+ _M_t._M_ptr() = pointer();
return __p;
}
reset(pointer __p = pointer()) noexcept
{
using std::swap;
- swap(std::get<0>(_M_t), __p);
+ swap(_M_t._M_ptr(), __p);
if (__p != pointer())
get_deleter()(__p);
}
template<typename _Tp, typename _Dp>
class unique_ptr<_Tp[], _Dp>
{
- // use SFINAE to determine whether _Del::pointer exists
- class _Pointer
- {
- template<typename _Up>
- static typename _Up::pointer __test(typename _Up::pointer*);
-
- template<typename _Up>
- static _Tp* __test(...);
-
- typedef typename remove_reference<_Dp>::type _Del;
-
- public:
- typedef decltype(__test<_Del>(0)) type;
- };
-
- typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type;
- __tuple_type _M_t;
+ __uniq_ptr_impl<_Tp, _Dp> _M_t;
template<typename _Up>
using __remove_cv = typename remove_cv<_Up>::type;
= __and_< is_base_of<_Tp, _Up>,
__not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
-
public:
- typedef typename _Pointer::type pointer;
- typedef _Tp element_type;
- typedef _Dp deleter_type;
+ using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
+ using element_type = _Tp;
+ using deleter_type = _Dp;
// helper template for detecting a safe conversion from another
// unique_ptr
__safe_conversion_raw<_Up>::value, bool>::type>
explicit
unique_ptr(_Up __p) noexcept
- : _M_t(__p, deleter_type())
+ : _M_t(__p)
{ static_assert(!is_pointer<deleter_type>::value,
"constructed with null function pointer deleter"); }
/// Destructor, invokes the deleter if the stored pointer is not null.
~unique_ptr()
{
- auto& __ptr = std::get<0>(_M_t);
+ auto& __ptr = _M_t._M_ptr();
if (__ptr != nullptr)
get_deleter()(__ptr);
__ptr = pointer();
/// Return the stored pointer.
pointer
get() const noexcept
- { return std::get<0>(_M_t); }
+ { return _M_t._M_ptr(); }
/// Return a reference to the stored deleter.
deleter_type&
get_deleter() noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return a reference to the stored deleter.
const deleter_type&
get_deleter() const noexcept
- { return std::get<1>(_M_t); }
+ { return _M_t._M_deleter(); }
/// Return @c true if the stored pointer is not null.
explicit operator bool() const noexcept
release() noexcept
{
pointer __p = get();
- std::get<0>(_M_t) = pointer();
+ _M_t._M_ptr() = pointer();
return __p;
}
{
pointer __ptr = __p;
using std::swap;
- swap(std::get<0>(_M_t), __ptr);
+ swap(_M_t._M_ptr(), __ptr);
if (__ptr != nullptr)
get_deleter()(__ptr);
}