EricWF created this revision.
EricWF added a reviewer: mclow.lists.
EricWF added subscribers: cfe-commits, loladiro.

__compressed_pair takes and passes it's constructor arguments by value. This 
causes arguments to be moved 3 times instead of once. This patch addresses that 
issue and fixes `constexpr` on the constructors.


https://reviews.llvm.org/D27564

Files:
  include/__hash_table
  include/memory
  include/string
  
test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp

Index: test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
===================================================================
--- test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
+++ test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
@@ -21,7 +21,6 @@
 class Deleter
 {
     // expected-error@memory:* {{base class 'Deleter' has private default constructor}}
-    // expected-note@memory:* + {{in instantiation of member function}}
     Deleter() {} // expected-note {{implicitly declared private here}}
 
 public:
Index: include/string
===================================================================
--- include/string
+++ include/string
@@ -1478,7 +1478,7 @@
 #else
         _NOEXCEPT
 #endif
-: __r_(__a)
+: __r_(__second_tag(), __a)
 {
 #if _LIBCPP_DEBUG_LEVEL >= 2
     __get_db()->__insert_c(this);
@@ -1549,7 +1549,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
     __init(__s, traits_type::length(__s));
@@ -1572,7 +1572,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
     __init(__s, __n);
@@ -1583,7 +1583,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str)
-    : __r_(__alloc_traits::select_on_container_copy_construction(__str.__alloc()))
+    : __r_(__second_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc()))
 {
     if (!__str.__is_long())
         __r_.first().__r = __str.__r_.first().__r;
@@ -1596,7 +1596,7 @@
 
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     if (!__str.__is_long())
         __r_.first().__r = __str.__r_.first().__r;
@@ -1630,7 +1630,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
         __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size());
@@ -1685,7 +1685,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     __init(__n, __c);
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1696,7 +1696,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
                                                         const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     size_type __str_sz = __str.size();
     if (__pos > __str_sz)
@@ -1711,7 +1711,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
                                                         const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     size_type __str_sz = __str.size();
     if (__pos > __str_sz)
@@ -1727,7 +1727,7 @@
 basic_string<_CharT, _Traits, _Allocator>::basic_string(
              const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a,
 			 typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
 	__self_view __sv = __self_view(__t).substr(__pos, __n);
     __init(__sv.data(), __sv.size());
@@ -1749,7 +1749,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     __init(__sv.data(), __sv.size());
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1831,7 +1831,7 @@
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last,
                                                         const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     __init(__first, __last);
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1854,7 +1854,7 @@
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_INLINE_VISIBILITY
 basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
-    : __r_(__a)
+    : __r_(__second_tag(), __a)
 {
     __init(__il.begin(), __il.end());
 #if _LIBCPP_DEBUG_LEVEL >= 2
Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -638,7 +638,7 @@
 #include <tuple>
 #include <stdexcept>
 #include <cstring>
-
+#include <cassert>
 #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 #  include <atomic>
 #endif
@@ -2081,6 +2081,10 @@
 template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
 class __libcpp_compressed_pair_imp;
 
+struct __first_tag {};
+struct __second_tag {};
+struct __args_tag {};
+
 template <class _T1, class _T2>
 class __libcpp_compressed_pair_imp<_T1, _T2, 0>
 {
@@ -2097,28 +2101,54 @@
     typedef const typename remove_reference<_T1>::type& _T1_const_reference;
     typedef const typename remove_reference<_T2>::type& _T2_const_reference;
 
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_(), __second_() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
-        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
-        : __first_(), __second_(_VSTD::forward<_T2_param>(__t2)) {}
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
-        : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() = default;
+  
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__first_tag, _Arg&& __a)
+        : __first_(std::forward<_Arg>(__a)), __second_() {}
+  
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__second_tag, _Arg&& __a)
+        : __first_(), __second_(std::forward<_Arg>(__a)) {}
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__args_tag, _U1&& __t1, _U2&& __t2)
+      : __first_(std::forward<_U1>(__t1)), __second_(std::forward<_U2>(__t2)) {}
 
     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
-        _LIBCPP_INLINE_VISIBILITY
-        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
-                                     tuple<_Args1...> __first_args,
-                                     tuple<_Args2...> __second_args,
-                                     __tuple_indices<_I1...>,
-                                     __tuple_indices<_I2...>)
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                           tuple<_Args1...> __first_args,
+                                           tuple<_Args2...> __second_args,
+                                           __tuple_indices<_I1...>,
+                                           __tuple_indices<_I2...>)
             : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
               __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
             {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() : __first_(), __second_() {}
+    
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__first_tag, _Arg& __a)
+        : __first_(__a), __second_() {}
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY 
+    __libcpp_compressed_pair_imp(__second_tag, _Arg& __a)
+        : __first_(), __second_(__a) {}
+
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__args_tag, _U1& __t1, _U2& __t2)
+      : __first_(__t1), __second_(__t2) {}
+#endif  // _LIBCPP_CXX03_LANG
 
     _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
     _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}
@@ -2141,6 +2171,7 @@
     : private _T1
 {
 private:
+  typedef _T1 __first_;
     _T2 __second_;
 public:
     typedef _T1 _T1_param;
@@ -2152,28 +2183,54 @@
     typedef const _T1&                                        _T1_const_reference;
     typedef const typename remove_reference<_T2>::type& _T2_const_reference;
 
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __second_() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
-        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
-        : __second_(_VSTD::forward<_T2_param>(__t2)) {}
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
-        : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() = default;
+  
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__first_tag, _Arg&& __a)
+        : __first_(std::forward<_Arg>(__a)), __second_() {}
+  
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__second_tag, _Arg&& __a)
+        : __first_(), __second_(std::forward<_Arg>(__a)) {}
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__args_tag, _U1&& __t1, _U2&& __t2)
+      : __first_(std::forward<_U1>(__t1)), __second_(std::forward<_U2>(__t2)) {}
 
     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
-        _LIBCPP_INLINE_VISIBILITY
-        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
-                                     tuple<_Args1...> __first_args,
-                                     tuple<_Args2...> __second_args,
-                                     __tuple_indices<_I1...>,
-                                     __tuple_indices<_I2...>)
-            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                           tuple<_Args1...> __first_args,
+                                           tuple<_Args2...> __second_args,
+                                           __tuple_indices<_I1...>,
+                                           __tuple_indices<_I2...>)
+            : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
               __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
             {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() : __first_(), __second_() {}
+    
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__first_tag, _Arg& __a)
+        : __first_(__a), __second_() {}
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY 
+    __libcpp_compressed_pair_imp(__second_tag, _Arg& __a)
+        : __first_(), __second_(__a) {}
+
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__args_tag, _U1& __t1, _U2& __t2)
+      : __first_(__t1), __second_(__t2) {}
+#endif  // _LIBCPP_CXX03_LANG
 
     _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}
     _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}
@@ -2196,6 +2253,7 @@
 {
 private:
     _T1 __first_;
+  typedef _T2 __second_;
 public:
     typedef _T1 _T1_param;
     typedef _T2 _T2_param;
@@ -2206,31 +2264,55 @@
     typedef const typename remove_reference<_T1>::type& _T1_const_reference;
     typedef const _T2&                                        _T2_const_reference;
 
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
-        : __first_(_VSTD::forward<_T1_param>(__t1)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
-        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_() {}
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
-        _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
-                   is_nothrow_move_constructible<_T2>::value)
-        : _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() = default;
+  
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__first_tag, _Arg&& __a)
+        : __second_(), __first_(std::forward<_Arg>(__a)) {}
+  
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__second_tag, _Arg&& __a)
+        : __second_(std::forward<_Arg>(__a)), __first_() {}
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__args_tag, _U1&& __t1, _U2&& __t2)
+      : __second_(std::forward<_U2>(__t2)), __first_(std::forward<_U1>(__t1)) {}
 
     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
-        _LIBCPP_INLINE_VISIBILITY
-        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
-                                     tuple<_Args1...> __first_args,
-                                     tuple<_Args2...> __second_args,
-                                     __tuple_indices<_I1...>,
-                                     __tuple_indices<_I2...>)
-            : _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...),
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                           tuple<_Args1...> __first_args,
+                                           tuple<_Args2...> __second_args,
+                                           __tuple_indices<_I1...>,
+                                           __tuple_indices<_I2...>)
+            : __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...),
               __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...)
-              
             {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() : __second_(), __first_() {}
+    
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__first_tag, _Arg& __a)
+        : __second_(), __first_(__a) {}
+
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY 
+    __libcpp_compressed_pair_imp(__second_tag, _Arg& __a)
+        : __second_(__a), __first_() {}
+
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__args_tag, _U1& __t1, _U2& __t2)
+      : __second_(__t2), __first_(__t1) {}
+#endif  // _LIBCPP_CXX03_LANG
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
 
     _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return __first_;}
     _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;}
@@ -2252,6 +2334,9 @@
     : private _T1,
       private _T2
 {
+private:
+  typedef _T1 __first_;
+  typedef _T2 __second_;
 public:
     typedef _T1 _T1_param;
     typedef _T2 _T2_param;
@@ -2262,28 +2347,54 @@
     typedef const _T1& _T1_const_reference;
     typedef const _T2& _T2_const_reference;
 
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
-        : _T1(_VSTD::forward<_T1_param>(__t1)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
-        : _T2(_VSTD::forward<_T2_param>(__t2)) {}
-    _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
-        : _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {}
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() = default;
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__first_tag, _Arg&& __a)
+        : __first_(std::forward<_Arg>(__a)), __second_() {}
+
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__second_tag, _Arg&& __a)
+        : __first_(), __second_(std::forward<_Arg>(__a)) {}
+
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(__args_tag, _U1&& __t1, _U2&& __t2)
+      : __first_(std::forward<_U1>(__t1)), __second_(std::forward<_U2>(__t2)) {}
 
     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
-        _LIBCPP_INLINE_VISIBILITY
-        __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
-                                     tuple<_Args1...> __first_args,
-                                     tuple<_Args2...> __second_args,
-                                     __tuple_indices<_I1...>,
-                                     __tuple_indices<_I2...>)
-            : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
-              _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
+    _LIBCPP_INLINE_VISIBILITY
+    constexpr __libcpp_compressed_pair_imp(piecewise_construct_t __pc,
+                                           tuple<_Args1...> __first_args,
+                                           tuple<_Args2...> __second_args,
+                                           __tuple_indices<_I1...>,
+                                           __tuple_indices<_I2...>)
+            : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...),
+              __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
             {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp() : __first_(), __second_() {}
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__first_tag, _Arg& __a)
+        : __first_(__a), __second_() {}
+
+    template <class _Arg>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__second_tag, _Arg& __a)
+        : __first_(), __second_(__a) {}
+
+    template <class _U1, class _U2>
+    _LIBCPP_INLINE_VISIBILITY
+    __libcpp_compressed_pair_imp(__args_tag, _U1& __t1, _U2& __t2)
+      : __first_(__t1), __second_(__t2) {}
+#endif  // _LIBCPP_CXX03_LANG
 
     _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return *this;}
     _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;}
@@ -2307,38 +2418,55 @@
     typedef typename base::_T1_param _T1_param;
     typedef typename base::_T2_param _T2_param;
 
-    typedef typename base::_T1_reference _T1_reference;
-    typedef typename base::_T2_reference _T2_reference;
-
-    typedef typename base::_T1_const_reference _T1_const_reference;
-    typedef typename base::_T2_const_reference _T2_const_reference;
-
-    _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
-    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)
-        : base(_VSTD::forward<_T1_param>(__t1)) {}
-    _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)
-        : base(_VSTD::forward<_T2_param>(__t2)) {}
-    _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
-        : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}
-
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+#ifndef _LIBCPP_CXX03_LANG
+  _LIBCPP_INLINE_VISIBILITY
+  __compressed_pair() = default;
+
+  template <class _Tp, typename enable_if<
+      !is_same<typename decay<_Tp>::type, __compressed_pair>::value, bool>::type = true
+  >
+  _LIBCPP_INLINE_VISIBILITY
+  constexpr explicit __compressed_pair(_Tp&& __t)
+      : base(__first_tag(), std::forward<_Tp>(__t)) {  }
+
+  template <class _Tp>
+  _LIBCPP_INLINE_VISIBILITY
+  constexpr __compressed_pair(__second_tag __tag, _Tp&& __t)
+      : base(__tag, std::forward<_Tp>(__t)) {}
+
+  template <class _U1, class _U2>
+  _LIBCPP_INLINE_VISIBILITY
+  constexpr __compressed_pair(_U1&& __t1, _U2&& __t2)
+      : base(__args_tag{}, std::forward<_U1>(__t1), std::forward<_U2>(__t2)) {}
 
     template <class... _Args1, class... _Args2>
-        _LIBCPP_INLINE_VISIBILITY
-        __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
-                                                      tuple<_Args2...> __second_args)
-            : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
-                   typename __make_tuple_indices<sizeof...(_Args1)>::type(),
-                   typename __make_tuple_indices<sizeof...(_Args2) >::type())
-            {}
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_CONSTEXPR_AFTER_CXX14
+    __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
+                                                  tuple<_Args2...> __second_args)
+        : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
+               typename __make_tuple_indices<sizeof...(_Args1)>::type(),
+               typename __make_tuple_indices<sizeof...(_Args2) >::type())
+        {}
 
-#endif  // _LIBCPP_HAS_NO_VARIADICS
+#else
+  _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __compressed_pair(_T1_param __t1)
+        : base(__first_tag(), _VSTD::forward<_T1_param>(__t1)) {}
 
-    _LIBCPP_INLINE_VISIBILITY _T1_reference       first() _NOEXCEPT       {return base::first();}
-    _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return base::first();}
+    _LIBCPP_INLINE_VISIBILITY
+    __compressed_pair(__second_tag __tag, _T2_param __t2)
+        : base(__tag, _VSTD::forward<_T2_param>(__t2)) {}
 
-    _LIBCPP_INLINE_VISIBILITY _T2_reference       second() _NOEXCEPT       {return base::second();}
-    _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return base::second();}
+    _LIBCPP_INLINE_VISIBILITY
+    __compressed_pair(_T1_param __t1, _T2_param __t2)
+        : base(__args_tag(), _VSTD::forward<_T1_param>(__t1),
+                             _VSTD::forward<_T2_param>(__t2)) {}
+#endif
+    using base::first;
+    using base::second;
 
     _LIBCPP_INLINE_VISIBILITY void swap(__compressed_pair& __x)
         _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
@@ -2383,7 +2511,7 @@
 template <class _Tp>
 struct _LIBCPP_TYPE_VIS_ONLY default_delete
 {
-#ifndef _LIBCPP_CXX03_LANG
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;
 #else
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {}
@@ -2403,7 +2531,7 @@
 struct _LIBCPP_TYPE_VIS_ONLY default_delete<_Tp[]>
 {
 public:
-#ifndef _LIBCPP_CXX03_LANG
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default;
 #else
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {}
Index: include/__hash_table
===================================================================
--- include/__hash_table
+++ include/__hash_table
@@ -1358,16 +1358,16 @@
                                                        const key_equal& __eql,
                                                        const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__second_tag(), __node_allocator(__a)),
       __p2_(0, __hf),
       __p3_(1.0f, __eql)
 {
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc>
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__second_tag(), __node_allocator(__a)),
       __p2_(0),
       __p3_(1.0f)
 {
@@ -1379,7 +1379,7 @@
           __bucket_list_deleter(allocator_traits<__pointer_allocator>::
               select_on_container_copy_construction(
                   __u.__bucket_list_.get_deleter().__alloc()), 0)),
-      __p1_(allocator_traits<__node_allocator>::
+      __p1_(__second_tag(), allocator_traits<__node_allocator>::
           select_on_container_copy_construction(__u.__node_alloc())),
       __p2_(0, __u.hash_function()),
       __p3_(__u.__p3_)
@@ -1390,7 +1390,7 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
                                                        const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__second_tag(), __node_allocator(__a)),
       __p2_(0, __u.hash_function()),
       __p3_(__u.__p3_)
 {
@@ -1424,7 +1424,7 @@
 __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
                                                        const allocator_type& __a)
     : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)),
-      __p1_(__node_allocator(__a)),
+      __p1_(__second_tag(), __node_allocator(__a)),
       __p2_(0, _VSTD::move(__u.hash_function())),
       __p3_(_VSTD::move(__u.__p3_))
 {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to