|
@@ -502,6 +502,28 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+template <bool _IsTuple, class _SizeTrait, size_t _Expected>
|
|
|
+struct __tuple_like_with_size_imp : false_type {};
|
|
|
+
|
|
|
+template <class _SizeTrait, size_t _Expected>
|
|
|
+struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected>
|
|
|
+ : integral_constant<bool, _SizeTrait::value == _Expected> {};
|
|
|
+
|
|
|
+template <class _Tuple, size_t _ExpectedSize,
|
|
|
+ class _RawTuple = typename __uncvref<_Tuple>::type>
|
|
|
+using __tuple_like_with_size = __tuple_like_with_size_imp<
|
|
|
+ __tuple_like<_RawTuple>::value,
|
|
|
+ tuple_size<_RawTuple>, _ExpectedSize
|
|
|
+ >;
|
|
|
+
|
|
|
+
|
|
|
+struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail {
|
|
|
+ template <class ...>
|
|
|
+ static constexpr bool __enable_explicit() { return false; }
|
|
|
+ template <class ...>
|
|
|
+ static constexpr bool __enable_implicit() { return false; }
|
|
|
+};
|
|
|
+
|
|
|
template <class ..._Tp>
|
|
|
class _LIBCPP_TYPE_VIS_ONLY tuple
|
|
|
{
|
|
@@ -509,6 +531,118 @@ class _LIBCPP_TYPE_VIS_ONLY tuple
|
|
|
|
|
|
base base_;
|
|
|
|
|
|
+ template <class ..._Args>
|
|
|
+ struct _PackExpandsToThisTuple : false_type {};
|
|
|
+
|
|
|
+ template <class _Arg>
|
|
|
+ struct _PackExpandsToThisTuple<_Arg>
|
|
|
+ : is_same<typename __uncvref<_Arg>::type, tuple> {};
|
|
|
+
|
|
|
+ template <bool _MaybeEnable, class _Dummy = void>
|
|
|
+ struct _CheckArgsConstructor : __check_tuple_constructor_fail {};
|
|
|
+
|
|
|
+ template <class _Dummy>
|
|
|
+ struct _CheckArgsConstructor<true, _Dummy>
|
|
|
+ {
|
|
|
+ template <class ..._Args>
|
|
|
+ static constexpr bool __enable_explicit() {
|
|
|
+ return
|
|
|
+ __tuple_constructible<
|
|
|
+ tuple<_Args...>,
|
|
|
+ typename __make_tuple_types<tuple,
|
|
|
+ sizeof...(_Args) < sizeof...(_Tp) ?
|
|
|
+ sizeof...(_Args) :
|
|
|
+ sizeof...(_Tp)>::type
|
|
|
+ >::value &&
|
|
|
+ !__tuple_convertible<
|
|
|
+ tuple<_Args...>,
|
|
|
+ typename __make_tuple_types<tuple,
|
|
|
+ sizeof...(_Args) < sizeof...(_Tp) ?
|
|
|
+ sizeof...(_Args) :
|
|
|
+ sizeof...(_Tp)>::type
|
|
|
+ >::value &&
|
|
|
+ __all_default_constructible<
|
|
|
+ typename __make_tuple_types<tuple, sizeof...(_Tp),
|
|
|
+ sizeof...(_Args) < sizeof...(_Tp) ?
|
|
|
+ sizeof...(_Args) :
|
|
|
+ sizeof...(_Tp)>::type
|
|
|
+ >::value;
|
|
|
+ }
|
|
|
+
|
|
|
+ template <class ..._Args>
|
|
|
+ static constexpr bool __enable_implicit() {
|
|
|
+ return
|
|
|
+ __tuple_convertible<
|
|
|
+ tuple<_Args...>,
|
|
|
+ typename __make_tuple_types<tuple,
|
|
|
+ sizeof...(_Args) < sizeof...(_Tp) ?
|
|
|
+ sizeof...(_Args) :
|
|
|
+ sizeof...(_Tp)>::type
|
|
|
+ >::value &&
|
|
|
+ __all_default_constructible<
|
|
|
+ typename __make_tuple_types<tuple, sizeof...(_Tp),
|
|
|
+ sizeof...(_Args) < sizeof...(_Tp) ?
|
|
|
+ sizeof...(_Args) :
|
|
|
+ sizeof...(_Tp)>::type
|
|
|
+ >::value;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template <bool _MaybeEnable,
|
|
|
+ bool = sizeof...(_Tp) == 1,
|
|
|
+ class _Dummy = void>
|
|
|
+ struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {};
|
|
|
+
|
|
|
+ template <class _Dummy>
|
|
|
+ struct _CheckTupleLikeConstructor<true, false, _Dummy>
|
|
|
+ {
|
|
|
+ template <class _Tuple>
|
|
|
+ static constexpr bool __enable_implicit() {
|
|
|
+ return __tuple_convertible<_Tuple, tuple>::value;
|
|
|
+ }
|
|
|
+
|
|
|
+ template <class _Tuple>
|
|
|
+ static constexpr bool __enable_explicit() {
|
|
|
+ return __tuple_constructible<_Tuple, tuple>::value
|
|
|
+ && !__tuple_convertible<_Tuple, tuple>::value;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ template <class _Dummy>
|
|
|
+ struct _CheckTupleLikeConstructor<true, true, _Dummy>
|
|
|
+ {
|
|
|
+ // This trait is used to disable the tuple-like constructor when
|
|
|
+ // the UTypes... constructor should be selected instead.
|
|
|
+ // See LWG issue #2549.
|
|
|
+ template <class _Tuple>
|
|
|
+ using _PreferTupleLikeConstructor = __lazy_or<
|
|
|
+ // Don't attempt the two checks below if the tuple we are given
|
|
|
+ // has the same type as this tuple.
|
|
|
+ is_same<typename __uncvref<_Tuple>::type, tuple>,
|
|
|
+ __lazy_and<
|
|
|
+ __lazy_not<is_constructible<_Tp..., _Tuple>>,
|
|
|
+ __lazy_not<is_convertible<_Tuple, _Tp...>>
|
|
|
+ >
|
|
|
+ >;
|
|
|
+
|
|
|
+ template <class _Tuple>
|
|
|
+ static constexpr bool __enable_implicit() {
|
|
|
+ return __lazy_and<
|
|
|
+ __tuple_convertible<_Tuple, tuple>,
|
|
|
+ _PreferTupleLikeConstructor<_Tuple>
|
|
|
+ >::value;
|
|
|
+ }
|
|
|
+
|
|
|
+ template <class _Tuple>
|
|
|
+ static constexpr bool __enable_explicit() {
|
|
|
+ return __lazy_and<
|
|
|
+ __tuple_constructible<_Tuple, tuple>,
|
|
|
+ _PreferTupleLikeConstructor<_Tuple>,
|
|
|
+ __lazy_not<__tuple_convertible<_Tuple, tuple>>
|
|
|
+ >::value;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
|
|
|
template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
@@ -562,21 +696,10 @@ public:
|
|
|
template <class ..._Up,
|
|
|
typename enable_if
|
|
|
<
|
|
|
- sizeof...(_Up) <= sizeof...(_Tp) &&
|
|
|
- __tuple_convertible
|
|
|
- <
|
|
|
- tuple<_Up...>,
|
|
|
- typename __make_tuple_types<tuple,
|
|
|
- sizeof...(_Up) < sizeof...(_Tp) ?
|
|
|
- sizeof...(_Up) :
|
|
|
- sizeof...(_Tp)>::type
|
|
|
- >::value &&
|
|
|
- __all_default_constructible<
|
|
|
- typename __make_tuple_types<tuple, sizeof...(_Tp),
|
|
|
- sizeof...(_Up) < sizeof...(_Tp) ?
|
|
|
- sizeof...(_Up) :
|
|
|
- sizeof...(_Tp)>::type
|
|
|
- >::value,
|
|
|
+ _CheckArgsConstructor<
|
|
|
+ sizeof...(_Up) <= sizeof...(_Tp)
|
|
|
+ && !_PackExpandsToThisTuple<_Up...>::value
|
|
|
+ >::template __enable_implicit<_Up...>(),
|
|
|
bool
|
|
|
>::type = false
|
|
|
>
|
|
@@ -600,31 +723,12 @@ public:
|
|
|
template <class ..._Up,
|
|
|
typename enable_if
|
|
|
<
|
|
|
- sizeof...(_Up) <= sizeof...(_Tp) &&
|
|
|
- __tuple_constructible
|
|
|
- <
|
|
|
- tuple<_Up...>,
|
|
|
- typename __make_tuple_types<tuple,
|
|
|
- sizeof...(_Up) < sizeof...(_Tp) ?
|
|
|
- sizeof...(_Up) :
|
|
|
- sizeof...(_Tp)>::type
|
|
|
- >::value &&
|
|
|
- !__tuple_convertible
|
|
|
- <
|
|
|
- tuple<_Up...>,
|
|
|
- typename __make_tuple_types<tuple,
|
|
|
- sizeof...(_Up) < sizeof...(_Tp) ?
|
|
|
- sizeof...(_Up) :
|
|
|
- sizeof...(_Tp)>::type
|
|
|
- >::value &&
|
|
|
- __all_default_constructible<
|
|
|
- typename __make_tuple_types<tuple, sizeof...(_Tp),
|
|
|
- sizeof...(_Up) < sizeof...(_Tp) ?
|
|
|
- sizeof...(_Up) :
|
|
|
- sizeof...(_Tp)>::type
|
|
|
- >::value,
|
|
|
+ _CheckArgsConstructor<
|
|
|
+ sizeof...(_Up) <= sizeof...(_Tp)
|
|
|
+ && !_PackExpandsToThisTuple<_Up...>::value
|
|
|
+ >::template __enable_explicit<_Up...>(),
|
|
|
bool
|
|
|
- >::type =false
|
|
|
+ >::type = false
|
|
|
>
|
|
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
|
|
|
explicit
|
|
@@ -647,8 +751,10 @@ public:
|
|
|
template <class _Alloc, class ..._Up,
|
|
|
class = typename enable_if
|
|
|
<
|
|
|
- sizeof...(_Up) == sizeof...(_Tp) &&
|
|
|
- __tuple_convertible<tuple<_Up...>, tuple>::value
|
|
|
+ _CheckArgsConstructor<
|
|
|
+ sizeof...(_Up) == sizeof...(_Tp) &&
|
|
|
+ !_PackExpandsToThisTuple<_Up...>::value
|
|
|
+ >::template __enable_implicit<_Up...>()
|
|
|
>::type
|
|
|
>
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
@@ -663,7 +769,10 @@ public:
|
|
|
template <class _Tuple,
|
|
|
typename enable_if
|
|
|
<
|
|
|
- __tuple_convertible<_Tuple, tuple>::value,
|
|
|
+ _CheckTupleLikeConstructor<
|
|
|
+ __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
|
|
|
+ && !_PackExpandsToThisTuple<_Tuple>::value
|
|
|
+ >::template __enable_implicit<_Tuple>(),
|
|
|
bool
|
|
|
>::type = false
|
|
|
>
|
|
@@ -674,8 +783,10 @@ public:
|
|
|
template <class _Tuple,
|
|
|
typename enable_if
|
|
|
<
|
|
|
- __tuple_constructible<_Tuple, tuple>::value &&
|
|
|
- !__tuple_convertible<_Tuple, tuple>::value,
|
|
|
+ _CheckTupleLikeConstructor<
|
|
|
+ __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
|
|
|
+ && !_PackExpandsToThisTuple<_Tuple>::value
|
|
|
+ >::template __enable_explicit<_Tuple>(),
|
|
|
bool
|
|
|
>::type = false
|
|
|
>
|
|
@@ -687,7 +798,9 @@ public:
|
|
|
template <class _Alloc, class _Tuple,
|
|
|
class = typename enable_if
|
|
|
<
|
|
|
- __tuple_convertible<_Tuple, tuple>::value
|
|
|
+ _CheckTupleLikeConstructor<
|
|
|
+ __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
|
|
|
+ >::template __enable_implicit<_Tuple>()
|
|
|
>::type
|
|
|
>
|
|
|
_LIBCPP_INLINE_VISIBILITY
|