Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
is_tuple_like.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5///
6/// @file is_tuple_like.hpp
7/// @brief Provides the @c is_tuple_like_v<T> and @c is_pair_like_v<T> traits
8///
9
10#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_IS_TUPLE_LIKE_HPP_
11#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_IS_TUPLE_LIKE_HPP_
12
13// IWYU pragma: private, include "arene/base/type_traits.hpp"
14// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
15
16#include "arene/base/constraints/constraints.hpp"
17#include "arene/base/stdlib_choice/cstddef.hpp"
18#include "arene/base/stdlib_choice/declval.hpp"
19#include "arene/base/stdlib_choice/enable_if.hpp"
20#include "arene/base/stdlib_choice/is_convertible.hpp"
21#include "arene/base/stdlib_choice/remove_cv.hpp"
22#include "arene/base/stdlib_choice/remove_reference.hpp"
23#include "arene/base/stdlib_choice/tuple_element.hpp"
24#include "arene/base/stdlib_choice/tuple_size.hpp"
25#include "arene/base/tuple/detail/get.hpp"
26#include "arene/base/type_traits/remove_cvref.hpp"
27
28namespace arene {
29namespace base {
30
31namespace tuple_like_detail {
32
33/// @brief Readability alias for the type yielded by calling @c get on an instance of @c T
34/// @tparam T The CV-qualified type to try getting an element from
35/// @tparam Idx The index to check @c get<Idx> for
36template <typename T, std::size_t Idx>
37using get_result = decltype(tuple_detail::get<Idx>(std::declval<T>()));
38
39/// @brief Type trait to determine if @c get<Idx> on an instance of @c T yields a reference compatible with
40/// @c tuple_element_t<Idx, T>; that is, the @c get result binds to a @c tuple_element_t const&.
41/// @tparam T The type to check; types with a member function @c get<Idx>() use that, other types use ADL @c
42/// get<Idx>()
43/// @tparam Idx The index to check @c get<Idx> for
44template <typename T, std::size_t Idx, typename = constraints<>>
45extern constexpr bool get_result_is_tuple_element_ref = false;
46
47/// @brief specialization active when the convertibility check holds for all four value categories
48/// @tparam T The type to check; types with a member function @c get<Idx>() use that, other types use ADL @c get<Idx>()
49/// @tparam Idx The index to check @c get<Idx> for
50template <typename T, std::size_t Idx>
51extern constexpr bool get_result_is_tuple_element_ref<
52 T,
53 Idx,
54 constraints<std::enable_if_t<
55 std::is_convertible<get_result<T&, Idx>, std::tuple_element_t<Idx, T> const&>::value &&
56 std::is_convertible<get_result<T const&, Idx>, std::tuple_element_t<Idx, T const> const&>::value &&
57 std::is_convertible<get_result<T&&, Idx>, std::tuple_element_t<Idx, T> const&>::value &&
58 std::is_convertible<get_result<T const&&, Idx>, std::tuple_element_t<Idx, T const> const&>::value //
59 >>> = true;
60
61} // namespace tuple_like_detail
62
63/// @brief Type trait to check if a type implements the tuple protocol
64/// @note A type implements the tuple protocol if it has @c get<Idx>() functions and specializations of
65/// @c std::tuple_size and <c>std::tuple_element</c>. The @c get<Idx>() implementations can either be member functions
66/// or free functions found by ADL; if both are present, the member functions are preferred.
67///
68/// Types implementing the tuple protocol can be used with structured bindings. Standard classes like <c>std::tuple</c>,
69/// <c>std::pair</c>, and <c>std::array</c> implement the tuple protocol, as does <c>arene::base::array</c>.
70///
71/// This trait checks that @c get<0>() and @c get<size-1>() both return types that are reference-compatible with
72/// <c>tuple_element</c> at the same index (convertible to <c>tuple_element_t const&</c>, for each of the four value
73/// categories of @c T). Intermediate indices are not checked for performance reasons. If <c>tuple_size<T> == 0</c>,
74/// the type is considered to be tuple-like regardless of the presence or behaviour of @c get and
75/// <c>tuple_element</c>.
76/// @tparam T The type to check
77template <typename T, typename = constraints<>>
78extern constexpr bool is_tuple_like_v = false;
79
80/// @brief Type trait to check if a type implements the tuple protocol
81/// @note A type implements the tuple protocol if it has @c get<Idx>() functions and specializations of
82/// @c std::tuple_size and <c>std::tuple_element</c>. The @c get<Idx>() implementations can either be member functions
83/// or free functions found by ADL; if both are present, the member functions are preferred.
84///
85/// Types implementing the tuple protocol can be used with structured bindings. Standard classes like <c>std::tuple</c>,
86/// <c>std::pair</c>, and <c>std::array</c> implement the tuple protocol, as does <c>arene::base::array</c>.
87///
88/// This trait checks that @c get<0>() and @c get<size-1>() both return types that are reference-compatible with
89/// <c>tuple_element</c> at the same index (convertible to <c>tuple_element_t const&</c>, for each of the four value
90/// categories of @c T). Intermediate indices are not checked for performance reasons. If <c>tuple_size<T> == 0</c>,
91/// the type is considered to be tuple-like regardless of the presence or behaviour of @c get and
92/// <c>tuple_element</c>.
93/// @tparam T The type to check
94template <typename T>
95extern constexpr bool
97
98/// @brief Type trait to check if a type implements the tuple protocol
99/// @note A type implements the tuple protocol if it has @c get<Idx>() functions and specializations of
100/// @c std::tuple_size and <c>std::tuple_element</c>. The @c get<Idx>() implementations can either be member functions
101/// or free functions found by ADL; if both are present, the member functions are preferred.
102///
103/// Types implementing the tuple protocol can be used with structured bindings. Standard classes like <c>std::tuple</c>,
104/// <c>std::pair</c>, and <c>std::array</c> implement the tuple protocol, as does <c>arene::base::array</c>.
105///
106/// This trait checks that @c get<0>() and @c get<size-1>() both return types that are reference-compatible with
107/// <c>tuple_element</c> at the same index (convertible to <c>tuple_element_t const&</c>, for each of the four value
108/// categories of @c T). Intermediate indices are not checked for performance reasons. If <c>tuple_size<T> == 0</c>,
109/// the type is considered to be tuple-like regardless of the presence or behaviour of @c get and
110/// <c>tuple_element</c>.
111/// @tparam T The type to check
112template <typename T>
113extern constexpr bool is_tuple_like_v<
114 T,
120 std::tuple_size<remove_cvref_t<T>>::value - 1U>>>> = true;
121
122/// @brief Type trait to check if a type implements the tuple protocol and has a @c std::tuple_size of 2
123/// @tparam T The type to check
124template <typename T, typename = constraints<>>
125extern constexpr bool is_pair_like_v = false;
126
127/// @brief Type trait to check if a type implements the tuple protocol and has a @c std::tuple_size of 2
128/// @tparam T The type to check
129template <typename T>
130extern constexpr bool
133
134} // namespace base
135} // namespace arene
136
137#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_IS_TUPLE_LIKE_HPP_
Definition array_exceptions_disabled.cpp:11
constexpr bool is_pair_like_v
Type trait to check if a type implements the tuple protocol and has a std::tuple_size of 2.
constexpr bool is_tuple_like_v
Type trait to check if a type implements the tuple protocol.
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10