[libcxx-commits] [libcxx] 21d6636 - [libc++] Split std::unique_ptr out of <memory>

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 13 05:22:35 PDT 2021


Author: Louis Dionne
Date: 2021-04-13T08:21:40-04:00
New Revision: 21d6636d83b377396c7cf01ee6332e70c2ed6605

URL: https://github.com/llvm/llvm-project/commit/21d6636d83b377396c7cf01ee6332e70c2ed6605
DIFF: https://github.com/llvm/llvm-project/commit/21d6636d83b377396c7cf01ee6332e70c2ed6605.diff

LOG: [libc++] Split std::unique_ptr out of <memory>

Differential Revision: https://reviews.llvm.org/D100318

Added: 
    libcxx/include/__memory/unique_ptr.h

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/memory
    libcxx/test/libcxx/containers/unord/unord.set/missing_hash_specialization.fail.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 0fa262d49d7d9..b63e0ebc29eb6 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -22,6 +22,7 @@ set(files
   __memory/raw_storage_iterator.h
   __memory/temporary_buffer.h
   __memory/uninitialized_algorithms.h
+  __memory/unique_ptr.h
   __memory/utilities.h
   __mutex_base
   __node_handle

diff  --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
new file mode 100644
index 0000000000000..355b259c1b87a
--- /dev/null
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -0,0 +1,764 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
+#define _LIBCPP___MEMORY_UNIQUE_PTR_H
+
+#include <__config>
+#include <__functional_base> // std::less
+#include <__memory/allocator_traits.h> // __pointer
+#include <__memory/auto_ptr.h>
+#include <__memory/compressed_pair.h>
+#include <cstddef>
+#include <type_traits>
+#include <utility>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS default_delete {
+    static_assert(!is_function<_Tp>::value,
+                  "default_delete cannot be instantiated for function types");
+#ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
+#else
+  _LIBCPP_INLINE_VISIBILITY default_delete() {}
+#endif
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  default_delete(const default_delete<_Up>&,
+                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
+                     0) _NOEXCEPT {}
+
+  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
+    static_assert(sizeof(_Tp) > 0,
+                  "default_delete can not delete incomplete type");
+    static_assert(!is_void<_Tp>::value,
+                  "default_delete can not delete incomplete type");
+    delete __ptr;
+  }
+};
+
+template <class _Tp>
+struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
+private:
+  template <class _Up>
+  struct _EnableIfConvertible
+      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
+
+public:
+#ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
+#else
+  _LIBCPP_INLINE_VISIBILITY default_delete() {}
+#endif
+
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  default_delete(const default_delete<_Up[]>&,
+                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
+
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  typename _EnableIfConvertible<_Up>::type
+  operator()(_Up* __ptr) const _NOEXCEPT {
+    static_assert(sizeof(_Tp) > 0,
+                  "default_delete can not delete incomplete type");
+    static_assert(!is_void<_Tp>::value,
+                  "default_delete can not delete void type");
+    delete[] __ptr;
+  }
+};
+
+template <class _Deleter>
+struct __unique_ptr_deleter_sfinae {
+  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
+  typedef const _Deleter& __lval_ref_type;
+  typedef _Deleter&& __good_rval_ref_type;
+  typedef true_type __enable_rval_overload;
+};
+
+template <class _Deleter>
+struct __unique_ptr_deleter_sfinae<_Deleter const&> {
+  typedef const _Deleter& __lval_ref_type;
+  typedef const _Deleter&& __bad_rval_ref_type;
+  typedef false_type __enable_rval_overload;
+};
+
+template <class _Deleter>
+struct __unique_ptr_deleter_sfinae<_Deleter&> {
+  typedef _Deleter& __lval_ref_type;
+  typedef _Deleter&& __bad_rval_ref_type;
+  typedef false_type __enable_rval_overload;
+};
+
+#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
+#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+#else
+#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
+#endif
+
+template <class _Tp, class _Dp = default_delete<_Tp> >
+class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
+public:
+  typedef _Tp element_type;
+  typedef _Dp deleter_type;
+  typedef _LIBCPP_NODEBUG_TYPE typename __pointer<_Tp, deleter_type>::type pointer;
+
+  static_assert(!is_rvalue_reference<deleter_type>::value,
+                "the specified deleter type cannot be an rvalue reference");
+
+private:
+  __compressed_pair<pointer, deleter_type> __ptr_;
+
+  struct __nat { int __for_bool_; };
+
+  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
+
+  template <bool _Dummy>
+  using _LValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
+
+  template <bool _Dummy>
+  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
+
+  template <bool _Dummy>
+  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
+
+  template <bool _Dummy, class _Deleter = typename __dependent_type<
+                             __identity<deleter_type>, _Dummy>::type>
+  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
+      typename enable_if<is_default_constructible<_Deleter>::value &&
+                         !is_pointer<_Deleter>::value>::type;
+
+  template <class _ArgType>
+  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
+      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
+
+  template <class _UPtr, class _Up>
+  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      is_convertible<typename _UPtr::pointer, pointer>::value &&
+      !is_array<_Up>::value
+  >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
+      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
+    >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterAssignable = typename enable_if<
+      is_assignable<_Dp&, _UDel&&>::value
+    >::type;
+
+public:
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, __d) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, _VSTD::move(__d)) {
+    static_assert(!is_reference<deleter_type>::value,
+                  "rvalue deleter bound to reference");
+  }
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterConvertible<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(auto_ptr<_Up>&& __p,
+             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
+                                    is_same<_Dp, default_delete<_Tp> >::value,
+                                __nat>::type = __nat()) _NOEXCEPT
+      : __ptr_(__p.release(), __default_init_tag()) {}
+#endif
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+    return *this;
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterAssignable<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
+    return *this;
+  }
+
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
+  template <class _Up>
+  _LIBCPP_INLINE_VISIBILITY
+      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
+                             is_same<_Dp, default_delete<_Tp> >::value,
+                         unique_ptr&>::type
+      operator=(auto_ptr<_Up> __p) {
+    reset(__p.release());
+    return *this;
+  }
+#endif
+
+#ifdef _LIBCPP_CXX03_LANG
+  unique_ptr(unique_ptr const&) = delete;
+  unique_ptr& operator=(unique_ptr const&) = delete;
+#endif
+
+
+  _LIBCPP_INLINE_VISIBILITY
+  ~unique_ptr() { reset(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
+    reset();
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename add_lvalue_reference<_Tp>::type
+  operator*() const {
+    return *__ptr_.first();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  pointer operator->() const _NOEXCEPT {
+    return __ptr_.first();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  pointer get() const _NOEXCEPT {
+    return __ptr_.first();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  deleter_type& get_deleter() _NOEXCEPT {
+    return __ptr_.second();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  const deleter_type& get_deleter() const _NOEXCEPT {
+    return __ptr_.second();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
+    return __ptr_.first() != nullptr;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  pointer release() _NOEXCEPT {
+    pointer __t = __ptr_.first();
+    __ptr_.first() = pointer();
+    return __t;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void reset(pointer __p = pointer()) _NOEXCEPT {
+    pointer __tmp = __ptr_.first();
+    __ptr_.first() = __p;
+    if (__tmp)
+      __ptr_.second()(__tmp);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void swap(unique_ptr& __u) _NOEXCEPT {
+    __ptr_.swap(__u.__ptr_);
+  }
+};
+
+
+template <class _Tp, class _Dp>
+class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
+public:
+  typedef _Tp element_type;
+  typedef _Dp deleter_type;
+  typedef typename __pointer<_Tp, deleter_type>::type pointer;
+
+private:
+  __compressed_pair<pointer, deleter_type> __ptr_;
+
+  template <class _From>
+  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
+
+  template <class _FromElem>
+  struct _CheckArrayPointerConversion<_FromElem*>
+      : integral_constant<bool,
+          is_same<_FromElem*, pointer>::value ||
+            (is_same<pointer, element_type*>::value &&
+             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
+      >
+  {};
+
+  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
+
+  template <bool _Dummy>
+  using _LValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
+
+  template <bool _Dummy>
+  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
+
+  template <bool _Dummy>
+  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
+      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
+
+  template <bool _Dummy, class _Deleter = typename __dependent_type<
+                             __identity<deleter_type>, _Dummy>::type>
+  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
+      typename enable_if<is_default_constructible<_Deleter>::value &&
+                         !is_pointer<_Deleter>::value>::type;
+
+  template <class _ArgType>
+  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
+      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
+
+  template <class _Pp>
+  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      _CheckArrayPointerConversion<_Pp>::value
+  >::type;
+
+  template <class _UPtr, class _Up,
+        class _ElemT = typename _UPtr::element_type>
+  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      is_array<_Up>::value &&
+      is_same<pointer, element_type*>::value &&
+      is_same<typename _UPtr::pointer, _ElemT*>::value &&
+      is_convertible<_ElemT(*)[], element_type(*)[]>::value
+    >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
+      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
+    >::type;
+
+  template <class _UDel>
+  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
+      is_assignable<_Dp&, _UDel&&>::value
+    >::type;
+
+public:
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  explicit unique_ptr(_Pp __p) _NOEXCEPT
+      : __ptr_(__p, __default_init_tag()) {}
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, __d) {}
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(nullptr, __d) {}
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(__p, _VSTD::move(__d)) {
+    static_assert(!is_reference<deleter_type>::value,
+                  "rvalue deleter bound to reference");
+  }
+
+  template <bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
+      : __ptr_(nullptr, _VSTD::move(__d)) {
+    static_assert(!is_reference<deleter_type>::value,
+                  "rvalue deleter bound to reference");
+  }
+
+  template <class _Pp, bool _Dummy = true,
+            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
+            class = _EnableIfPointerConvertible<_Pp> >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
+    return *this;
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterConvertible<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
+      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
+  }
+
+  template <class _Up, class _Ep,
+      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
+      class = _EnableIfDeleterAssignable<_Ep>
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr&
+  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
+    reset(__u.release());
+    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
+    return *this;
+  }
+
+#ifdef _LIBCPP_CXX03_LANG
+  unique_ptr(unique_ptr const&) = delete;
+  unique_ptr& operator=(unique_ptr const&) = delete;
+#endif
+
+public:
+  _LIBCPP_INLINE_VISIBILITY
+  ~unique_ptr() { reset(); }
+
+  _LIBCPP_INLINE_VISIBILITY
+  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
+    reset();
+    return *this;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  typename add_lvalue_reference<_Tp>::type
+  operator[](size_t __i) const {
+    return __ptr_.first()[__i];
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  pointer get() const _NOEXCEPT {
+    return __ptr_.first();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  deleter_type& get_deleter() _NOEXCEPT {
+    return __ptr_.second();
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  const deleter_type& get_deleter() const _NOEXCEPT {
+    return __ptr_.second();
+  }
+  _LIBCPP_INLINE_VISIBILITY
+  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
+    return __ptr_.first() != nullptr;
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  pointer release() _NOEXCEPT {
+    pointer __t = __ptr_.first();
+    __ptr_.first() = pointer();
+    return __t;
+  }
+
+  template <class _Pp>
+  _LIBCPP_INLINE_VISIBILITY
+  typename enable_if<
+      _CheckArrayPointerConversion<_Pp>::value
+  >::type
+  reset(_Pp __p) _NOEXCEPT {
+    pointer __tmp = __ptr_.first();
+    __ptr_.first() = __p;
+    if (__tmp)
+      __ptr_.second()(__tmp);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void reset(nullptr_t = nullptr) _NOEXCEPT {
+    pointer __tmp = __ptr_.first();
+    __ptr_.first() = nullptr;
+    if (__tmp)
+      __ptr_.second()(__tmp);
+  }
+
+  _LIBCPP_INLINE_VISIBILITY
+  void swap(unique_ptr& __u) _NOEXCEPT {
+    __ptr_.swap(__u.__ptr_);
+  }
+
+};
+
+template <class _Tp, class _Dp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<
+    __is_swappable<_Dp>::value,
+    void
+>::type
+swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+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 <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
+
+template <class _T1, class _D1, class _T2, class _D2>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
+{
+    return !__x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
+{
+    return static_cast<bool>(__x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+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 <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+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 <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return nullptr < __x;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return __x < nullptr;
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(nullptr < __x);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
+{
+    return !(__x < nullptr);
+}
+
+template <class _T1, class _D1>
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
+{
+    return !(nullptr < __x);
+}
+
+#if _LIBCPP_STD_VER > 11
+
+template<class _Tp>
+struct __unique_if
+{
+    typedef unique_ptr<_Tp> __unique_single;
+};
+
+template<class _Tp>
+struct __unique_if<_Tp[]>
+{
+    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
+};
+
+template<class _Tp, size_t _Np>
+struct __unique_if<_Tp[_Np]>
+{
+    typedef void __unique_array_known_bound;
+};
+
+template<class _Tp, class... _Args>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_single
+make_unique(_Args&&... __args)
+{
+    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
+}
+
+template<class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename __unique_if<_Tp>::__unique_array_unknown_bound
+make_unique(size_t __n)
+{
+    typedef typename remove_extent<_Tp>::type _Up;
+    return unique_ptr<_Tp>(new _Up[__n]());
+}
+
+template<class _Tp, class... _Args>
+    typename __unique_if<_Tp>::__unique_array_known_bound
+    make_unique(_Args&&...) = delete;
+
+#endif  // _LIBCPP_STD_VER > 11
+
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash;
+
+template <class _Tp, class _Dp>
+#ifdef _LIBCPP_CXX03_LANG
+struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
+#else
+struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
+    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
+#endif
+{
+    typedef unique_ptr<_Tp, _Dp> argument_type;
+    typedef size_t               result_type;
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(const argument_type& __ptr) const
+    {
+        typedef typename argument_type::pointer pointer;
+        return hash<pointer>()(__ptr.get());
+    }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif  // _LIBCPP___MEMORY_UNIQUE_PTR_H

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 609439e0687d6..8ce8517a71d91 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -688,6 +688,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 #include <__memory/raw_storage_iterator.h>
 #include <__memory/temporary_buffer.h>
 #include <__memory/uninitialized_algorithms.h>
+#include <__memory/unique_ptr.h>
 #include <__memory/utilities.h>
 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #  include <atomic>
@@ -815,735 +816,6 @@ void __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp*
         _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
 }
 
-// default_delete
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS default_delete {
-    static_assert(!is_function<_Tp>::value,
-                  "default_delete cannot be instantiated for function types");
-#ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
-#else
-  _LIBCPP_INLINE_VISIBILITY default_delete() {}
-#endif
-  template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  default_delete(const default_delete<_Up>&,
-                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
-                     0) _NOEXCEPT {}
-
-  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
-    static_assert(sizeof(_Tp) > 0,
-                  "default_delete can not delete incomplete type");
-    static_assert(!is_void<_Tp>::value,
-                  "default_delete can not delete incomplete type");
-    delete __ptr;
-  }
-};
-
-template <class _Tp>
-struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
-private:
-  template <class _Up>
-  struct _EnableIfConvertible
-      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
-
-public:
-#ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
-#else
-  _LIBCPP_INLINE_VISIBILITY default_delete() {}
-#endif
-
-  template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  default_delete(const default_delete<_Up[]>&,
-                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
-
-  template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  typename _EnableIfConvertible<_Up>::type
-  operator()(_Up* __ptr) const _NOEXCEPT {
-    static_assert(sizeof(_Tp) > 0,
-                  "default_delete can not delete incomplete type");
-    static_assert(!is_void<_Tp>::value,
-                  "default_delete can not delete void type");
-    delete[] __ptr;
-  }
-};
-
-template <class _Deleter>
-struct __unique_ptr_deleter_sfinae {
-  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
-  typedef const _Deleter& __lval_ref_type;
-  typedef _Deleter&& __good_rval_ref_type;
-  typedef true_type __enable_rval_overload;
-};
-
-template <class _Deleter>
-struct __unique_ptr_deleter_sfinae<_Deleter const&> {
-  typedef const _Deleter& __lval_ref_type;
-  typedef const _Deleter&& __bad_rval_ref_type;
-  typedef false_type __enable_rval_overload;
-};
-
-template <class _Deleter>
-struct __unique_ptr_deleter_sfinae<_Deleter&> {
-  typedef _Deleter& __lval_ref_type;
-  typedef _Deleter&& __bad_rval_ref_type;
-  typedef false_type __enable_rval_overload;
-};
-
-#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
-#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
-#else
-#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
-#endif
-
-template <class _Tp, class _Dp = default_delete<_Tp> >
-class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
-public:
-  typedef _Tp element_type;
-  typedef _Dp deleter_type;
-  typedef _LIBCPP_NODEBUG_TYPE typename __pointer<_Tp, deleter_type>::type pointer;
-
-  static_assert(!is_rvalue_reference<deleter_type>::value,
-                "the specified deleter type cannot be an rvalue reference");
-
-private:
-  __compressed_pair<pointer, deleter_type> __ptr_;
-
-  struct __nat { int __for_bool_; };
-
-  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
-
-  template <bool _Dummy>
-  using _LValRefType _LIBCPP_NODEBUG_TYPE =
-      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
-
-  template <bool _Dummy>
-  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
-      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
-
-  template <bool _Dummy>
-  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
-      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
-
-  template <bool _Dummy, class _Deleter = typename __dependent_type<
-                             __identity<deleter_type>, _Dummy>::type>
-  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
-      typename enable_if<is_default_constructible<_Deleter>::value &&
-                         !is_pointer<_Deleter>::value>::type;
-
-  template <class _ArgType>
-  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
-      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
-
-  template <class _UPtr, class _Up>
-  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
-      is_convertible<typename _UPtr::pointer, pointer>::value &&
-      !is_array<_Up>::value
-  >::type;
-
-  template <class _UDel>
-  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
-      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
-      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
-    >::type;
-
-  template <class _UDel>
-  using _EnableIfDeleterAssignable = typename enable_if<
-      is_assignable<_Dp&, _UDel&&>::value
-    >::type;
-
-public:
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
-  _LIBCPP_INLINE_VISIBILITY
-  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(__p, __d) {}
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(__p, _VSTD::move(__d)) {
-    static_assert(!is_reference<deleter_type>::value,
-                  "rvalue deleter bound to reference");
-  }
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
-
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
-  }
-
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterConvertible<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
-
-#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
-  template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(auto_ptr<_Up>&& __p,
-             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
-                                    is_same<_Dp, default_delete<_Tp> >::value,
-                                __nat>::type = __nat()) _NOEXCEPT
-      : __ptr_(__p.release(), __default_init_tag()) {}
-#endif
-
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
-    reset(__u.release());
-    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
-    return *this;
-  }
-
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterAssignable<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
-    reset(__u.release());
-    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
-    return *this;
-  }
-
-#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
-  template <class _Up>
-  _LIBCPP_INLINE_VISIBILITY
-      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
-                             is_same<_Dp, default_delete<_Tp> >::value,
-                         unique_ptr&>::type
-      operator=(auto_ptr<_Up> __p) {
-    reset(__p.release());
-    return *this;
-  }
-#endif
-
-#ifdef _LIBCPP_CXX03_LANG
-  unique_ptr(unique_ptr const&) = delete;
-  unique_ptr& operator=(unique_ptr const&) = delete;
-#endif
-
-
-  _LIBCPP_INLINE_VISIBILITY
-  ~unique_ptr() { reset(); }
-
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
-    reset();
-    return *this;
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  typename add_lvalue_reference<_Tp>::type
-  operator*() const {
-    return *__ptr_.first();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  pointer operator->() const _NOEXCEPT {
-    return __ptr_.first();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  pointer get() const _NOEXCEPT {
-    return __ptr_.first();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  deleter_type& get_deleter() _NOEXCEPT {
-    return __ptr_.second();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  const deleter_type& get_deleter() const _NOEXCEPT {
-    return __ptr_.second();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
-    return __ptr_.first() != nullptr;
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  pointer release() _NOEXCEPT {
-    pointer __t = __ptr_.first();
-    __ptr_.first() = pointer();
-    return __t;
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  void reset(pointer __p = pointer()) _NOEXCEPT {
-    pointer __tmp = __ptr_.first();
-    __ptr_.first() = __p;
-    if (__tmp)
-      __ptr_.second()(__tmp);
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  void swap(unique_ptr& __u) _NOEXCEPT {
-    __ptr_.swap(__u.__ptr_);
-  }
-};
-
-
-template <class _Tp, class _Dp>
-class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
-public:
-  typedef _Tp element_type;
-  typedef _Dp deleter_type;
-  typedef typename __pointer<_Tp, deleter_type>::type pointer;
-
-private:
-  __compressed_pair<pointer, deleter_type> __ptr_;
-
-  template <class _From>
-  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
-
-  template <class _FromElem>
-  struct _CheckArrayPointerConversion<_FromElem*>
-      : integral_constant<bool,
-          is_same<_FromElem*, pointer>::value ||
-            (is_same<pointer, element_type*>::value &&
-             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
-      >
-  {};
-
-  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
-
-  template <bool _Dummy>
-  using _LValRefType _LIBCPP_NODEBUG_TYPE =
-      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
-
-  template <bool _Dummy>
-  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
-      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
-
-  template <bool _Dummy>
-  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
-      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
-
-  template <bool _Dummy, class _Deleter = typename __dependent_type<
-                             __identity<deleter_type>, _Dummy>::type>
-  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
-      typename enable_if<is_default_constructible<_Deleter>::value &&
-                         !is_pointer<_Deleter>::value>::type;
-
-  template <class _ArgType>
-  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
-      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
-
-  template <class _Pp>
-  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
-      _CheckArrayPointerConversion<_Pp>::value
-  >::type;
-
-  template <class _UPtr, class _Up,
-        class _ElemT = typename _UPtr::element_type>
-  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
-      is_array<_Up>::value &&
-      is_same<pointer, element_type*>::value &&
-      is_same<typename _UPtr::pointer, _ElemT*>::value &&
-      is_convertible<_ElemT(*)[], element_type(*)[]>::value
-    >::type;
-
-  template <class _UDel>
-  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
-      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
-      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
-    >::type;
-
-  template <class _UDel>
-  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
-      is_assignable<_Dp&, _UDel&&>::value
-    >::type;
-
-public:
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
-
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  explicit unique_ptr(_Pp __p) _NOEXCEPT
-      : __ptr_(__p, __default_init_tag()) {}
-
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(__p, __d) {}
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(nullptr, __d) {}
-
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(__p, _VSTD::move(__d)) {
-    static_assert(!is_reference<deleter_type>::value,
-                  "rvalue deleter bound to reference");
-  }
-
-  template <bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
-      : __ptr_(nullptr, _VSTD::move(__d)) {
-    static_assert(!is_reference<deleter_type>::value,
-                  "rvalue deleter bound to reference");
-  }
-
-  template <class _Pp, bool _Dummy = true,
-            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
-            class = _EnableIfPointerConvertible<_Pp> >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
-
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
-    reset(__u.release());
-    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
-    return *this;
-  }
-
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterConvertible<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
-      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
-  }
-
-  template <class _Up, class _Ep,
-      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
-      class = _EnableIfDeleterAssignable<_Ep>
-  >
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr&
-  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
-    reset(__u.release());
-    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
-    return *this;
-  }
-
-#ifdef _LIBCPP_CXX03_LANG
-  unique_ptr(unique_ptr const&) = delete;
-  unique_ptr& operator=(unique_ptr const&) = delete;
-#endif
-
-public:
-  _LIBCPP_INLINE_VISIBILITY
-  ~unique_ptr() { reset(); }
-
-  _LIBCPP_INLINE_VISIBILITY
-  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
-    reset();
-    return *this;
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  typename add_lvalue_reference<_Tp>::type
-  operator[](size_t __i) const {
-    return __ptr_.first()[__i];
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  pointer get() const _NOEXCEPT {
-    return __ptr_.first();
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  deleter_type& get_deleter() _NOEXCEPT {
-    return __ptr_.second();
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  const deleter_type& get_deleter() const _NOEXCEPT {
-    return __ptr_.second();
-  }
-  _LIBCPP_INLINE_VISIBILITY
-  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
-    return __ptr_.first() != nullptr;
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  pointer release() _NOEXCEPT {
-    pointer __t = __ptr_.first();
-    __ptr_.first() = pointer();
-    return __t;
-  }
-
-  template <class _Pp>
-  _LIBCPP_INLINE_VISIBILITY
-  typename enable_if<
-      _CheckArrayPointerConversion<_Pp>::value
-  >::type
-  reset(_Pp __p) _NOEXCEPT {
-    pointer __tmp = __ptr_.first();
-    __ptr_.first() = __p;
-    if (__tmp)
-      __ptr_.second()(__tmp);
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  void reset(nullptr_t = nullptr) _NOEXCEPT {
-    pointer __tmp = __ptr_.first();
-    __ptr_.first() = nullptr;
-    if (__tmp)
-      __ptr_.second()(__tmp);
-  }
-
-  _LIBCPP_INLINE_VISIBILITY
-  void swap(unique_ptr& __u) _NOEXCEPT {
-    __ptr_.swap(__u.__ptr_);
-  }
-
-};
-
-template <class _Tp, class _Dp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if<
-    __is_swappable<_Dp>::value,
-    void
->::type
-swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
-
-template <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
-
-template <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
-
-template <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-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 <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
-
-template <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
-
-template <class _T1, class _D1, class _T2, class _D2>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
-{
-    return !__x;
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
-{
-    return !__x;
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
-{
-    return static_cast<bool>(__x);
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
-{
-    return static_cast<bool>(__x);
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-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 <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-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 <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    return nullptr < __x;
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    return __x < nullptr;
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    return !(nullptr < __x);
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    return !(__x < nullptr);
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
-{
-    return !(__x < nullptr);
-}
-
-template <class _T1, class _D1>
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
-{
-    return !(nullptr < __x);
-}
-
-#if _LIBCPP_STD_VER > 11
-
-template<class _Tp>
-struct __unique_if
-{
-    typedef unique_ptr<_Tp> __unique_single;
-};
-
-template<class _Tp>
-struct __unique_if<_Tp[]>
-{
-    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
-};
-
-template<class _Tp, size_t _Np>
-struct __unique_if<_Tp[_Np]>
-{
-    typedef void __unique_array_known_bound;
-};
-
-template<class _Tp, class... _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __unique_if<_Tp>::__unique_single
-make_unique(_Args&&... __args)
-{
-    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
-}
-
-template<class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __unique_if<_Tp>::__unique_array_unknown_bound
-make_unique(size_t __n)
-{
-    typedef typename remove_extent<_Tp>::type _Up;
-    return unique_ptr<_Tp>(new _Up[__n]());
-}
-
-template<class _Tp, class... _Args>
-    typename __unique_if<_Tp>::__unique_array_known_bound
-    make_unique(_Args&&...) = delete;
-
-#endif  // _LIBCPP_STD_VER > 11
-
-template <class _Tp, class _Dp>
-#ifdef _LIBCPP_CXX03_LANG
-struct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
-#else
-struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
-    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
-#endif
-{
-    typedef unique_ptr<_Tp, _Dp> argument_type;
-    typedef size_t               result_type;
-    _LIBCPP_INLINE_VISIBILITY
-    result_type operator()(const argument_type& __ptr) const
-    {
-        typedef typename argument_type::pointer pointer;
-        return hash<pointer>()(__ptr.get());
-    }
-};
-
 struct __destruct_n
 {
 private:

diff  --git a/libcxx/test/libcxx/containers/unord/unord.set/missing_hash_specialization.fail.cpp b/libcxx/test/libcxx/containers/unord/unord.set/missing_hash_specialization.fail.cpp
index a4c10f68fe216..390e0e523cf1f 100644
--- a/libcxx/test/libcxx/containers/unord/unord.set/missing_hash_specialization.fail.cpp
+++ b/libcxx/test/libcxx/containers/unord/unord.set/missing_hash_specialization.fail.cpp
@@ -13,6 +13,9 @@
 // newer.
 // UNSUPPORTED: c++11
 
+// Clang doesn't support filename wildcards in verify tests until 05eedf1f5b44.
+// UNSUPPORTED: clang-10
+
 // <unordered_set>
 
 // Test that we generate a reasonable diagnostic when the specified hash is
@@ -52,7 +55,7 @@ int main(int, char**) {
   // FIXME: It would be great to suppress the below diagnostic all together.
   //        but for now it's sufficient that it appears last. However there is
   //        currently no way to test the order diagnostics are issued.
-  // expected-error at memory:* {{call to implicitly-deleted default constructor of 'std::}}
+  // expected-error@*:* {{call to implicitly-deleted default constructor of 'std::}}
   }
   {
     using Set = std::unordered_set<int, BadHashNoCopy>;


        


More information about the libcxx-commits mailing list