struct tuple_element<1, pair<_Tp1, _Tp2>>
{ typedef _Tp2 type; };
+#if __cplusplus >= 201703L
+ template<typename _Tp1, typename _Tp2>
+ inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
+
+ template<typename _Tp1, typename _Tp2>
+ inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
+#endif
+
/// @cond undocumented
template<size_t _Int>
struct __pair_get;
struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>>
: public tuple_size<_Tp> { };
+#if __cplusplus >= 201703L
+ template<typename _Tp>
+ inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
+#endif
+
/// Gives the type of the ith element of a given tuple type.
template<size_t __i, typename _Tp>
struct tuple_element;
};
#if __cplusplus >= 201402L
-// The standard says this macro and alias template should be in <tuple>
-// but we define them here, to be available in <utility> and <array> too.
+// The standard says this macro and alias template should be in <tuple> but we
+// we define them here, to be available in <array>, <utility> and <ranges> too.
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 3378. tuple_size_v/tuple_element_t should be available when
+// tuple_size/tuple_element are
#define __cpp_lib_tuple_element_t 201402L
template<size_t __i, typename _Tp>
#endif // C++17
#endif // C++14
+ template<size_t _Np, typename... _Types>
+ struct _Nth_type
+ { };
+
+ template<typename _Tp0, typename... _Rest>
+ struct _Nth_type<0, _Tp0, _Rest...>
+ { using type = _Tp0; };
+
+ template<typename _Tp0, typename _Tp1, typename... _Rest>
+ struct _Nth_type<1, _Tp0, _Tp1, _Rest...>
+ { using type = _Tp1; };
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
+ struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...>
+ { using type = _Tp2; };
+
+ template<size_t _Np, typename _Tp0, typename _Tp1, typename _Tp2,
+ typename... _Rest>
+#if __cpp_concepts
+ requires (_Np >= 3)
+#endif
+ struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...>
+ : _Nth_type<_Np - 3, _Rest...>
+ { };
+
+#if ! __cpp_concepts // Need additional specializations to avoid ambiguities.
+ template<typename _Tp0, typename _Tp1, typename... _Rest>
+ struct _Nth_type<0, _Tp0, _Tp1, _Rest...>
+ { using type = _Tp0; };
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
+ struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...>
+ { using type = _Tp0; };
+
+ template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
+ struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...>
+ { using type = _Tp1; };
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
using type = _Tp;
};
+#if __cplusplus >= 201703L
+ template<typename _Tp, size_t _Nm>
+ inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm;
+
+ template<typename _Tp, size_t _Nm>
+ inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm;
+#endif
+
template<typename _Tp, size_t _Nm>
struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
{ };
struct tuple_size<tuple<_Elements...>>
: public integral_constant<size_t, sizeof...(_Elements)> { };
-#if __cplusplus > 201402L
- template <typename _Tp>
- inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
-#endif
+#if __cplusplus >= 201703L
+ template<typename... _Types>
+ inline constexpr size_t tuple_size_v<tuple<_Types>>
+ = sizeof...(_Types);
- /**
- * Recursive case for tuple_element: strip off the first element in
- * the tuple and retrieve the (i-1)th element of the remaining tuple.
- */
- template<size_t __i, typename _Head, typename... _Tail>
- struct tuple_element<__i, tuple<_Head, _Tail...> >
- : tuple_element<__i - 1, tuple<_Tail...> > { };
+ template<typename... _Types>
+ inline constexpr size_t tuple_size_v<const tuple<_Types>>
+ = sizeof...(_Types);
+#endif
- /**
- * Basis case for tuple_element: The first element is the one we're seeking.
- */
- template<typename _Head, typename... _Tail>
- struct tuple_element<0, tuple<_Head, _Tail...> >
+ /// Trait to get the Ith element type from a tuple.
+ template<size_t __i, typename... _Types>
+ struct tuple_element<__i, tuple<_Types...>>
{
- typedef _Head type;
- };
+ static_assert(__i < sizeof...(_Types), "tuple index must be in range");
- /**
- * Error case for tuple_element: invalid index.
- */
- template<size_t __i>
- struct tuple_element<__i, tuple<>>
- {
- static_assert(__i < tuple_size<tuple<>>::value,
- "tuple index must be in range");
+ using type = typename _Nth_type<__i, _Types...>::type;
};
template<size_t __i, typename _Head, typename... _Tail>
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
-namespace __detail
-{
-namespace __variant
-{
- template<size_t _Np, typename... _Types>
- struct _Nth_type;
-
- template<typename _Tp0, typename... _Rest>
- struct _Nth_type<0, _Tp0, _Rest...>
- { using type = _Tp0; };
-
- template<typename _Tp0, typename _Tp1, typename... _Rest>
- struct _Nth_type<1, _Tp0, _Tp1, _Rest...>
- { using type = _Tp1; };
-
- template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
- struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...>
- { using type = _Tp2; };
-
- template<size_t _Np, typename _Tp0, typename _Tp1, typename _Tp2,
- typename... _Rest>
-#if __cpp_concepts
- requires (_Np >= 3)
-#endif
- struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...>
- : _Nth_type<_Np - 3, _Rest...>
- { };
-
-#if ! __cpp_concepts // Need additional specializations to avoid ambiguities.
- template<typename _Tp0, typename _Tp1, typename... _Rest>
- struct _Nth_type<0, _Tp0, _Tp1, _Rest...>
- { using type = _Tp0; };
-
- template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
- struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...>
- { using type = _Tp0; };
-
- template<typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
- struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...>
- { using type = _Tp1; };
-#endif
-
-} // namespace __variant
-} // namespace __detail
-
#if __cplusplus >= 202002L && __cpp_concepts
// P2231R1 constexpr needs constexpr unions and constrained destructors.
# define __cpp_lib_variant 202106L
{
static_assert(_Np < sizeof...(_Types));
- using type
- = typename __detail::__variant::_Nth_type<_Np, _Types...>::type;
+ using type = typename _Nth_type<_Np, _Types...>::type;
};
template<size_t _Np, typename _Variant>
= __detail::__variant::__accepted_index<_Tp, variant>::value;
template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>>
- using __to_type
- = typename __detail::__variant::_Nth_type<_Np, _Types...>::type;
+ using __to_type = typename _Nth_type<_Np, _Types...>::type;
template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>>
using __accepted_type = __to_type<__accepted_index<_Tp>>;
emplace(_Args&&... __args)
{
namespace __variant = std::__detail::__variant;
- using type = typename __variant::_Nth_type<_Np, _Types...>::type;
+ using type = typename _Nth_type<_Np, _Types...>::type;
// Provide the strong exception-safety guarantee when possible,
// to avoid becoming valueless.
if constexpr (is_nothrow_constructible_v<type, _Args...>)
emplace(initializer_list<_Up> __il, _Args&&... __args)
{
namespace __variant = std::__detail::__variant;
- using type = typename __variant::_Nth_type<_Np, _Types...>::type;
+ using type = typename _Nth_type<_Np, _Types...>::type;
// Provide the strong exception-safety guarantee when possible,
// to avoid becoming valueless.
if constexpr (is_nothrow_constructible_v<type,
constexpr size_t __max = 11; // "These go to eleven."
// The type of the first variant in the pack.
- using _V0
- = typename __detail::__variant::_Nth_type<0, _Variants...>::type;
+ using _V0 = typename _Nth_type<0, _Variants...>::type;
// The number of alternatives in that first variant.
constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
}
// { dg-error "tuple index must be in range" "" { target *-*-* } 0 }
+// { dg-prune-output "no type named 'type' in .*_Nth_type" }