[libc++] Take 2: Implement LWG 2510
Summary:
LWG2510 makes tag types like allocator_arg_t explicitly default
constructible instead of implicitly default constructible. It also
makes the constructors for std::pair and std::tuple conditionally
explicit based on the explicit-ness of the default constructibility
for the pair/tuple's elements.
This was previously committed as r372777 and reverted in r372832 due to
the commit breaking LLVM's build in C++14 mode. This issue has now been
addressed.
Reviewers: mclow.lists
Subscribers: christof, jkorous, dexonsmith, libcxx-commits
Tags: #libc
Differential Revision: https://reviews.llvm.org/D65161
llvm-svn: 372983
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: e16f2cb6789286dbfa4a184cef25b91dfb499206
diff --git a/include/tuple b/include/tuple
index 32bc869..c33b48a 100644
--- a/include/tuple
+++ b/include/tuple
@@ -19,7 +19,7 @@
template <class... T>
class tuple {
public:
- constexpr tuple();
+ explicit(see-below) constexpr tuple();
explicit(see-below) tuple(const T&...); // constexpr in C++14
template <class... U>
explicit(see-below) tuple(U&&...); // constexpr in C++14
@@ -500,8 +500,19 @@
struct _CheckArgsConstructor<true, _Dummy>
{
template <class ..._Args>
- static constexpr bool __enable_default() {
- return __all<is_default_constructible<_Args>::value...>::value;
+ static constexpr bool __enable_implicit_default() {
+ // In C++03, there's no way to implement the resolution of LWG2510.
+#ifdef _LIBCPP_CXX03_LANG
+ return true;
+#else
+ return __all<__is_implicitly_default_constructible<_Args>::value...>::value;
+#endif
+ }
+
+ template <class ..._Args>
+ static constexpr bool __enable_explicit_default() {
+ return __all<is_default_constructible<_Args>::value...>::value
+ && !__enable_implicit_default<_Args...>();
}
template <class ..._Args>
@@ -641,11 +652,18 @@
const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
public:
- template <bool _Dummy = true, class = typename enable_if<
- _CheckArgsConstructor<_Dummy>::template __enable_default<_Tp...>()
- >::type>
- _LIBCPP_INLINE_VISIBILITY
- _LIBCPP_CONSTEXPR tuple()
+ template <bool _Dummy = true, _EnableIf<
+ _CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...>()
+ , void*> = nullptr>
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+ tuple()
+ _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
+
+ template <bool _Dummy = true, _EnableIf<
+ _CheckArgsConstructor<_Dummy>::template __enable_explicit_default<_Tp...>()
+ , void*> = nullptr>
+ explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+ tuple()
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
tuple(tuple const&) = default;