Fix std::pair on FreeBSD

Summary:
FreeBSD ships an old ABI for std::pair which requires that it have non-trivial copy/move constructors. Currently the non-trivial copy/move is achieved by providing explicit definitions of the constructors. This is problematic because it means the constructors don't SFINAE properly. In order to SFINAE copy/move constructors they have to be explicitly defaulted and hense non-trivial.

This patch attempts to provide SFINAE'ing copy/move constructors for std::pair while still making them non-trivial. It does this by adding a base class with a non-trivial copy constructor and then allowing pair's constructors to be generated by the compiler. This also allows the constructors to be constexpr.


Reviewers: emaste, theraven, rsmith, dim

Subscribers: cfe-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@283944 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/utility b/include/utility
index 095748d..cfab350 100644
--- a/include/utility
+++ b/include/utility
@@ -291,9 +291,20 @@
 constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
 #endif
 
+#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
+struct __non_trivially_copyable_base {
+  _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
+  __non_trivially_copyable_base() _NOEXCEPT {}
+  _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
+  __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
+};
+#endif
 
 template <class _T1, class _T2>
 struct _LIBCPP_TYPE_VIS_ONLY pair
+#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
+: private __non_trivially_copyable_base
+#endif
 {
     typedef _T1 first_type;
     typedef _T2 second_type;
@@ -301,26 +312,7 @@
     _T1 first;
     _T2 second;
 
-#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
-    _LIBCPP_INLINE_VISIBILITY
-    pair(const pair& __p)
-        _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
-                   is_nothrow_copy_constructible<second_type>::value)
-        : first(__p.first),
-          second(__p.second)
-    {
-    }
-
-# ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY
-    pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value &&
-                                is_nothrow_move_constructible<second_type>::value)
-        : first(_VSTD::forward<first_type>(__p.first)),
-          second(_VSTD::forward<second_type>(__p.second))
-    {
-    }
-# endif
-#elif !defined(_LIBCPP_CXX03_LANG)
+#if !defined(_LIBCPP_CXX03_LANG)
     pair(pair const&) = default;
     pair(pair&&) = default;
 #else