Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
iterator_category_traits.hpp
Go to the documentation of this file.
1// Copyright 2024, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_ITERATOR_CATEGORY_TRAITS_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_ITERATOR_CATEGORY_TRAITS_HPP_
7
8// IWYU pragma: private, include "arene/base/type_traits.hpp"
9// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
10
11#include "arene/base/constraints/constraints.hpp"
12#include "arene/base/stdlib_choice/declval.hpp"
13#include "arene/base/stdlib_choice/enable_if.hpp"
14#include "arene/base/stdlib_choice/is_assignable.hpp"
15#include "arene/base/stdlib_choice/is_base_of.hpp"
16#include "arene/base/stdlib_choice/is_convertible.hpp"
17#include "arene/base/stdlib_choice/is_copy_assignable.hpp"
18#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
19#include "arene/base/stdlib_choice/is_default_constructible.hpp"
20#include "arene/base/stdlib_choice/is_integral.hpp"
21#include "arene/base/stdlib_choice/is_pointer.hpp"
22#include "arene/base/stdlib_choice/is_reference.hpp"
23#include "arene/base/stdlib_choice/is_same.hpp"
24#include "arene/base/stdlib_choice/is_signed.hpp"
25#include "arene/base/stdlib_choice/iterator_tags.hpp"
26#include "arene/base/stdlib_choice/iterator_traits.hpp"
27#include "arene/base/stdlib_choice/remove_cv.hpp"
28#include "arene/base/stdlib_choice/remove_reference.hpp"
29#include "arene/base/type_manipulation/give_qualifiers_to.hpp"
30#include "arene/base/type_manipulation/static_if.hpp"
31#include "arene/base/type_traits/comparison_traits.hpp"
32#include "arene/base/type_traits/remove_cvref.hpp"
33
34namespace arene {
35namespace base {
36
37namespace iterator_category_detail {
38/// Type trait to check if a type meets the basic syntactic requirements of an
39/// iterator:
40/// * There is a defined @c iterator_category for that type
41/// * The type is copy-constructible
42/// * The type is copy-assignable
43/// * The expression @c ++x yields a @c T&
44/// * The expression @c *x yields an object type
45/// * The expression @c *x++ yields an object type
46/// where @c x is an instance of @c T
47/// The value is @c true if the type meets the requirements, @c false otherwise.
48/// @tparam T The type being checked
49template <typename T, typename = constraints<>>
50constexpr bool is_basic_iterator_v = false;
51
52/// Specialization for types that do meet the syntactic requirements.
53/// @tparam T The type to check.
54template <typename T>
55constexpr bool is_basic_iterator_v<
56 T,
57 constraints<
58 typename std::iterator_traits<T>::iterator_category,
59 std::enable_if_t<std::is_copy_constructible<T>::value>,
60 std::enable_if_t<std::is_copy_assignable<T>::value>,
61 std::enable_if_t<std::is_same<T&, decltype(++std::declval<T&>())>::value>,
62 decltype(*std::declval<T&>())&,
63 decltype(*std::declval<T&>()++)&>> = true;
64
65/// A variable holding @c true if the specified type has an iterator category
66/// derived from @c std::output_iterator_tag or @c false otherwise.
67/// @tparam T The type to check.
68template <typename T, typename = constraints<>>
69constexpr bool has_output_iterator_category_v = false;
70
71/// Specialization for types that do have an output iterator category
72/// @tparam T The type to check.
73template <typename T>
74constexpr bool has_output_iterator_category_v<
75 T,
76 constraints<std::enable_if_t<
77 std::is_base_of<std::output_iterator_tag, typename std::iterator_traits<T>::iterator_category>::value>>> = true;
78
79/// @brief alias to apply the cv union of @c T1 and @c T2
80/// @tparam T1 first type with cv-qualifiers
81/// @tparam T2 second type with cv-qualifiers
82/// @tparam X type to apply the cv union qualifiers to
83// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
84template <class T1, class T2, class X>
85using add_cv_union_t = arene::base::give_qualifiers_to<T2, arene::base::give_qualifiers_to<T1, X>>;
86// parasoft-end-suppress AUTOSAR-A2_7_3
87
88/// @brief Helper trait to determine the simple common reference of two lvalue reference types
89/// @tparam T1 first lvalue reference type
90/// @tparam T2 second lvalue reference type
91// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
92template <typename T1, typename T2, typename = constraints<>>
93class simple_common_lvalue_reference {};
94// parasoft-end-suppress AUTOSAR-A2_7_3
95
96/// @brief Specialization if both types are lvalue reference types
97/// @tparam T1 first lvalue reference type
98/// @tparam T2 second lvalue reference type
99// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
100template <typename T1, typename T2>
101class simple_common_lvalue_reference<
102 T1&,
103 T2&,
104 constraints<std::enable_if_t<std::is_reference<
105 decltype(false ? std::declval<add_cv_union_t<T1, T2, T1>&>() : std::declval<add_cv_union_t<T1, T2, T2>&>())>::
106 value>>> {
107 public:
108 /// @brief simple common reference
109 using type =
110 decltype(false ? std::declval<add_cv_union_t<T1, T2, T1>&>() : std::declval<add_cv_union_t<T1, T2, T2>&>());
111};
112// parasoft-end-suppress AUTOSAR-A2_7_3
113
114/// @brief Helper alias to determine the simple common reference of two lvalue references
115/// @tparam T1 first lvalue reference type
116/// @tparam T2 second lvalue reference type
117// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
118template <typename T1, typename T2>
119using simple_common_lvalue_reference_t = typename simple_common_lvalue_reference<T1, T2>::type;
120// parasoft-end-suppress AUTOSAR-A2_7_3
121
122/// @brief Trait to determine the simple common reference of two reference types
123/// @tparam T1 first reference type
124/// @tparam T2 second reference type
125// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
126template <typename T1, typename T2, typename = constraints<>>
127class simple_common_reference {};
128// parasoft-end-suppress AUTOSAR-A2_7_3
129
130/// @brief Alias to determine the simple common reference of two reference types
131/// @tparam T1 first reference type
132/// @tparam T2 second reference type
133// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
134template <typename T1, typename T2>
135using simple_common_reference_t = typename simple_common_reference<T1, T2>::type;
136// parasoft-end-suppress AUTOSAR-A2_7_3
137
138/// @brief Specialization if both types are lvalue references
139/// @tparam T1 first reference type
140/// @tparam T2 second reference type
141// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
142template <typename T1, typename T2>
143class simple_common_reference<T1&, T2&, constraints<simple_common_lvalue_reference_t<T1&, T2&>>> {
144 public:
145 /// @brief simple common reference
146 using type = simple_common_lvalue_reference_t<T1&, T2&>;
147};
148// parasoft-end-suppress AUTOSAR-A2_7_3
149
150/// @brief Specialization if both types are rvalue references
151/// @tparam T1 first reference type
152/// @tparam T2 second reference type
153// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
154template <typename T1, typename T2>
155class simple_common_reference<
156 T1&&,
157 T2&&,
158 constraints<
159 std::enable_if_t<
160 std::is_convertible<T1&&, std::remove_reference_t<simple_common_reference_t<T1&, T2&>>&&>::value>,
161 std::enable_if_t<
162 std::is_convertible<T2&&, std::remove_reference_t<simple_common_reference_t<T1&, T2&>>&&>::value>>> {
163 public:
164 /// @brief simple common reference
165 using type = std::remove_reference_t<simple_common_reference_t<T1&, T2&>>&&;
166};
167// parasoft-end-suppress AUTOSAR-A2_7_3
168
169/// @brief Specialization if one type is an lvalue reference and the other type is an rvalue reference
170/// @tparam T1 first reference type
171/// @tparam T2 second reference type
172// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
173template <typename A, typename B>
174class simple_common_reference<
175 A&,
176 B&&,
177 constraints<std::enable_if_t<std::is_convertible<B&&, simple_common_reference_t<A&, B const&>>::value>>> {
178 public:
179 /// @brief simple common reference
180 using type = simple_common_reference_t<A&, B const&>;
181};
182// parasoft-end-suppress AUTOSAR-A2_7_3
183
184/// @brief Specialization if one type is an lvalue reference and the other type is an rvalue reference
185/// @tparam T1 first reference type
186/// @tparam T2 second reference type
187// parasoft-begin-suppress AUTOSAR-A2_7_3 "False positive: documented"
188template <typename A, typename B>
189class simple_common_reference<B&&, A&> : public simple_common_reference<A&, B&&> {};
190// parasoft-end-suppress AUTOSAR-A2_7_3
191
192/// @brief Trait to check if two types have a common type they are both convertible to.
193/// Resolves to @c true if they do, @c false otherwise.
194/// @tparam T The first type to check
195/// @tparam U The second type to check
196///
197/// @note This uses a simplification of std::common_reference
198///
199template <typename T, typename U, typename = constraints<>>
200constexpr bool have_common_type_v = false;
201
202/// Specialization for the case that @c T and @c U are both reference types.
203/// @tparam T The first type to check
204/// @tparam U The second type to check
205template <typename T, typename U>
206constexpr bool have_common_type_v<
207 T,
208 U,
209 constraints<
210 std::enable_if_t<std::is_reference<T>::value && std::is_reference<U>::value>,
211 simple_common_reference_t<T, U>>> = true;
212
213/// Specialization for the case that @c T and @c U do have a common type.
214/// @tparam T The first type to check
215/// @tparam U The second type to check
216template <typename T, typename U>
217constexpr bool have_common_type_v<
218 T,
219 U,
220 constraints<
221 std::enable_if_t<!(std::is_reference<T>::value && std::is_reference<U>::value)>,
222 decltype(false ? std::declval<T>() : std::declval<U>())>> = true;
223
224/// A variable for checking if a type has a valid iterator pointer trait. It is
225/// @c true if the type supports @c operator-> and @c
226/// std::iterator_traits<T>::pointer is the return type of @c operator->, and @c
227/// false otherwise.
228/// @tparam T The type being checked
229template <typename T, typename = constraints<>>
230constexpr bool has_valid_pointer_trait_v =
231 std::is_same<typename std::iterator_traits<T>::pointer, void>::value || std::is_pointer<T>::value;
232
233/// Specialization for the case that @c T does have an @c operator->
234/// @tparam T The type being checked
235template <typename T>
236constexpr bool has_valid_pointer_trait_v<T, constraints<decltype(std::declval<T&>().operator->())>> =
237 std::is_same<typename std::iterator_traits<T>::pointer, decltype(std::declval<T&>().operator->())>::value;
238
239} // namespace iterator_category_detail
240
241/// Type trait to check if a type is an output iterator
242/// The value is @c true if the type meets the requirements, @c false otherwise.
243/// @tparam T The type being checked
244template <typename T, typename = constraints<>>
245constexpr bool is_output_iterator_v = false;
246
247/// Specialization for types that meet the basic iterator requirements
248/// @tparam T The type being checked
249template <typename T>
250constexpr bool
253 std::is_assignable<decltype(*std::declval<T&>()++), typename std::iterator_traits<T>::value_type>::value;
254
255/// Type trait to check if a type is an input iterator
256/// The value is @c true if the type meets the requirements, @c false otherwise.
257/// @tparam T The type being checked
258template <typename T, typename = constraints<>>
259constexpr bool is_input_iterator_v = false;
260
261/// Specialization for types that meet the syntactic input iterator requirements
262/// @tparam T The type being checked
263template <typename T>
264constexpr bool is_input_iterator_v<
265 T,
268 typename std::iterator_traits<T>::reference&&,
269 typename std::iterator_traits<T>::value_type&,
277 std::is_same<decltype(*std::declval<T&>()), typename std::iterator_traits<T>::reference>::value>,
279 typename std::iterator_traits<T>::reference&&,
280 typename std::iterator_traits<T>::value_type&>>,
282 decltype(*std::declval<T&>()++)&&,
283 typename std::iterator_traits<T>::value_type&>>,
285
286/// Type trait to check if a type is a forward iterator
287/// The value is @c true if the type meets the requirements, @c false otherwise.
288/// @tparam T The type being checked
289template <typename T, typename = constraints<>>
290constexpr bool is_forward_iterator_v = false;
291
292/// Specialization for types that meet the input iterator requirements
293/// @tparam T The type being checked
294template <typename T>
296 T,
302 std::enable_if_t<std::is_same<T, decltype(std::declval<T&>()++)>::value>,
306 remove_cvref_t<typename std::iterator_traits<T>::reference>>::value>>> = true;
307
308/// Type trait to check if a type is a bidirectional iterator
309/// The value is @c true if the type meets the requirements, @c false otherwise.
310/// @tparam T The type being checked
311template <typename T, typename = constraints<>>
312constexpr bool is_bidirectional_iterator_v = false;
313
314/// Specialization for types that meet the syntactic requirements for a
315/// bidirectional iterator
316/// @tparam T The type being checked
317template <typename T>
319 T,
325 std::enable_if_t<std::is_same<T&, decltype(--std::declval<T&>())>::value>,
326 std::enable_if_t<std::is_same<T, decltype(std::declval<T&>()--)>::value>>> = true;
327
328/// Type trait to check if a type is a random-access iterator
329/// The value is @c true if the type meets the requirements, @c false otherwise.
330/// @tparam T The type being checked
331template <typename T, typename = constraints<>>
332constexpr bool is_random_access_iterator_v = false;
333
334/// Specialization for types that meets the syntactic requirements of a random
335/// access iterator
336/// @tparam T The type being checked
337template <typename T>
339 T,
346 decltype(std::declval<T&>() += std::declval<typename std::iterator_traits<T>::difference_type>()),
347 T&>::value>,
349 decltype(std::declval<T&>() + std::declval<typename std::iterator_traits<T>::difference_type>()),
350 T>::value>,
352 decltype(std::declval<typename std::iterator_traits<T>::difference_type>() + std::declval<T&>()),
353 T>::value>,
355 decltype(std::declval<T&>() -= std::declval<typename std::iterator_traits<T>::difference_type>()),
356 T&>::value>,
358 decltype(std::declval<T&>() - std::declval<typename std::iterator_traits<T>::difference_type>()),
359 T>::value>,
361 decltype(std::declval<T&>() - std::declval<T&>()),
364 decltype(std::declval<T&>()[std::declval<typename std::iterator_traits<T>::difference_type>()]),
365 typename std::iterator_traits<T>::reference>::value>,
370
371/// Type trait for checking if a type is an iterator.
372/// The value is @c true if the type meets the requirements, @c false otherwise.
373/// @tparam T The type being checked
374template <typename T>
375constexpr bool is_iterator_v =
377
378} // namespace base
379} // namespace arene
380
381#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_TYPE_TRAITS_ITERATOR_CATEGORY_TRAITS_HPP_
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10