diff options
Diffstat (limited to 'contrib/libc++/include/tuple')
-rw-r--r-- | contrib/libc++/include/tuple | 455 |
1 files changed, 357 insertions, 98 deletions
diff --git a/contrib/libc++/include/tuple b/contrib/libc++/include/tuple index cb1e27d..744a3ff 100644 --- a/contrib/libc++/include/tuple +++ b/contrib/libc++/include/tuple @@ -76,10 +76,18 @@ template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14 template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14 template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14 - + +// [tuple.apply], calling a function with a tuple of arguments: +template <class F, class Tuple> + constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 +template <class T, class Tuple> + constexpr T make_from_tuple(Tuple&& t); // C++17 + // 20.4.1.4, tuple helper classes: template <class T> class tuple_size; // undefined template <class... T> class tuple_size<tuple<T...>>; +template <class T> + constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 template <size_t I, class T> class tuple_element; // undefined template <size_t I, class... T> class tuple_element<I, tuple<T...>>; template <size_t I, class T> @@ -379,10 +387,8 @@ template <class ..._Tp> _LIBCPP_INLINE_VISIBILITY void __swallow(_Tp&&...) _NOEXCEPT {} -template <bool ..._Pred> -struct __all - : is_same<__all<_Pred...>, __all<(_Pred, true)...>> -{ }; +template <class ..._Tp> +struct __lazy_all : __all<_Tp::value...> {}; template <class _Tp> struct __all_default_constructible; @@ -446,7 +452,7 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> template <class _Alloc, class _Tuple, class = typename enable_if < - __tuple_convertible<_Tuple, tuple<_Tp...> >::value + __tuple_constructible<_Tuple, tuple<_Tp...> >::value >::type > _LIBCPP_INLINE_VISIBILITY @@ -499,6 +505,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 { @@ -506,6 +534,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 @@ -523,8 +663,30 @@ public: _LIBCPP_CONSTEXPR tuple() _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} + template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if< + __lazy_and< + is_same<allocator_arg_t, _AllocArgT>, + __lazy_all<__dependent_type<is_default_constructible<_Tp>, _Dummy>...> + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + tuple(_AllocArgT, _Alloc const& __a) + : base_(allocator_arg_t(), __a, + __tuple_indices<>(), __tuple_types<>(), + typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), + __tuple_types<_Tp...>()) {} + + template <bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_implicit<_Tp const&...>(), + bool + >::type = false + > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) + tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), typename __make_tuple_indices<0>::type(), @@ -532,8 +694,54 @@ public: __t... ) {} - template <class _Alloc> + template <bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_explicit<_Tp const&...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) + : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), + typename __make_tuple_indices<0>::type(), + typename __make_tuple_types<tuple, 0>::type(), + __t... + ) {} + + template <class _Alloc, bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_implicit<_Tp const&...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) + : base_(allocator_arg_t(), __a, + typename __make_tuple_indices<sizeof...(_Tp)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), + typename __make_tuple_indices<0>::type(), + typename __make_tuple_types<tuple, 0>::type(), + __t... + ) {} + + template <class _Alloc, bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_explicit<_Tp const&...>(), + bool + >::type = false + > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) : base_(allocator_arg_t(), __a, typename __make_tuple_indices<sizeof...(_Tp)>::type(), @@ -546,21 +754,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 > @@ -584,31 +781,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 @@ -629,26 +807,36 @@ public: _VSTD::forward<_Up>(__u)...) {} template <class _Alloc, class ..._Up, - class = typename enable_if + 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 - >::type + _CheckArgsConstructor< + sizeof...(_Up) == sizeof...(_Tp) && + !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_implicit<_Up...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) + : base_(allocator_arg_t(), __a, + typename __make_tuple_indices<sizeof...(_Up)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), + typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), + _VSTD::forward<_Up>(__u)...) {} + + template <class _Alloc, class ..._Up, + typename enable_if + < + _CheckArgsConstructor< + sizeof...(_Up) == sizeof...(_Tp) && + !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_explicit<_Up...>(), + bool + >::type = false > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) : base_(allocator_arg_t(), __a, typename __make_tuple_indices<sizeof...(_Up)>::type(), @@ -660,7 +848,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 > @@ -671,8 +862,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 > @@ -682,12 +875,29 @@ public: : base_(_VSTD::forward<_Tuple>(__t)) {} template <class _Alloc, class _Tuple, - class = typename enable_if + typename enable_if < - __tuple_convertible<_Tuple, tuple>::value - >::type + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + >::template __enable_implicit<_Tuple>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) + : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} + + template <class _Alloc, class _Tuple, + typename enable_if + < + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + >::template __enable_explicit<_Tuple>(), + bool + >::type = false > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} @@ -784,39 +994,44 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT } #if _LIBCPP_STD_VER > 11 -// get by type -template <typename _T1, size_t _Idx, typename... _Args> -struct __find_exactly_one_t_helper; - -// -- find exactly one -template <typename _T1, size_t _Idx, typename... _Args> -struct __find_exactly_one_t_checker { - static constexpr size_t value = _Idx; -// Check the rest of the list to make sure there's only one - static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" ); - }; +namespace __find_detail { -template <typename _T1, size_t _Idx> -struct __find_exactly_one_t_helper <_T1, _Idx> { - static constexpr size_t value = -1; - }; +static constexpr size_t __not_found = -1; +static constexpr size_t __ambiguous = __not_found - 1; -template <typename _T1, size_t _Idx, typename _Head, typename... _Args> -struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> { - static constexpr size_t value = - std::conditional< - std::is_same<_T1, _Head>::value, - __find_exactly_one_t_checker<_T1, _Idx, _Args...>, - __find_exactly_one_t_helper <_T1, _Idx+1, _Args...> - >::type::value; - }; +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { + return !__matches ? __res : + (__res == __not_found ? __curr_i : __ambiguous); +} + +template <size_t _Nx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { + return __i == _Nx ? __not_found : + __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]); +} + +template <class _T1, class ..._Args> +struct __find_exactly_one_checked { + static constexpr bool __matches[] = {is_same<_T1, _Args>::value...}; + static constexpr size_t value = __find_detail::__find_idx(0, __matches); + static_assert (value != __not_found, "type not found in type list" ); + static_assert(value != __ambiguous,"type occurs more than once in type list"); +}; + +template <class _T1> +struct __find_exactly_one_checked<_T1> { + static_assert(!is_same<_T1, _T1>::value, "type not in empty type list"); +}; + +} // namespace __find_detail; template <typename _T1, typename... _Args> -struct __find_exactly_one_t { - static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value; - static_assert ( value != -1, "type not found in type list" ); - }; +struct __find_exactly_one_t + : public __find_detail::__find_exactly_one_checked<_T1, _Args...> { +}; template <class _T1, class... _Args> inline _LIBCPP_INLINE_VISIBILITY @@ -1154,6 +1369,50 @@ pair<_T1, _T2>::pair(piecewise_construct_t, #endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t tuple_size_v = tuple_size<_Tp>::value; + +#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } + +template <class _Fn, class _Tuple, size_t ..._Id> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, + __tuple_indices<_Id...>) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__invoke_constexpr( + _VSTD::forward<_Fn>(__f), + _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...) +) + +template <class _Fn, class _Tuple> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__apply_tuple_impl( + _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), + typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) +) + +template <class _Tp, class _Tuple, size_t... _Idx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>) +_LIBCPP_NOEXCEPT_RETURN( + _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...) +) + +template <class _Tp, class _Tuple> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp make_from_tuple(_Tuple&& __t) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t), + typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) +) + +#undef _LIBCPP_NOEXCEPT_RETURN + +#endif // _LIBCPP_STD_VER > 14 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TUPLE |