1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP___ITERATOR_READABLE_TRAITS_H |
11 | #define _LIBCPP___ITERATOR_READABLE_TRAITS_H |
12 | |
13 | #include <__concepts/same_as.h> |
14 | #include <__config> |
15 | #include <__type_traits/conditional.h> |
16 | #include <__type_traits/is_array.h> |
17 | #include <__type_traits/is_object.h> |
18 | #include <__type_traits/is_primary_template.h> |
19 | #include <__type_traits/remove_cv.h> |
20 | #include <__type_traits/remove_cvref.h> |
21 | #include <__type_traits/remove_extent.h> |
22 | |
23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
24 | # pragma GCC system_header |
25 | #endif |
26 | |
27 | _LIBCPP_BEGIN_NAMESPACE_STD |
28 | |
29 | #if _LIBCPP_STD_VER >= 20 |
30 | |
31 | // [readable.traits] |
32 | template <class> |
33 | struct __cond_value_type {}; |
34 | |
35 | template <class _Tp> |
36 | requires is_object_v<_Tp> |
37 | struct __cond_value_type<_Tp> { |
38 | using value_type = remove_cv_t<_Tp>; |
39 | }; |
40 | |
41 | template <class _Tp> |
42 | concept __has_member_value_type = requires { typename _Tp::value_type; }; |
43 | |
44 | template <class _Tp> |
45 | concept __has_member_element_type = requires { typename _Tp::element_type; }; |
46 | |
47 | template <class> |
48 | struct indirectly_readable_traits {}; |
49 | |
50 | template <class _Ip> |
51 | requires is_array_v<_Ip> |
52 | struct indirectly_readable_traits<_Ip> { |
53 | using value_type = remove_cv_t<remove_extent_t<_Ip>>; |
54 | }; |
55 | |
56 | template <class _Ip> |
57 | struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {}; |
58 | |
59 | template <class _Tp> |
60 | struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; |
61 | |
62 | template <__has_member_value_type _Tp> |
63 | struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::value_type> {}; |
64 | |
65 | template <__has_member_element_type _Tp> |
66 | struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::element_type> {}; |
67 | |
68 | template <__has_member_value_type _Tp> |
69 | requires __has_member_element_type<_Tp> |
70 | struct indirectly_readable_traits<_Tp> {}; |
71 | |
72 | template <__has_member_value_type _Tp> |
73 | requires __has_member_element_type<_Tp> && |
74 | same_as<remove_cv_t<typename _Tp::element_type>, remove_cv_t<typename _Tp::value_type>> |
75 | struct indirectly_readable_traits<_Tp> : __cond_value_type<typename _Tp::value_type> {}; |
76 | |
77 | #endif // _LIBCPP_STD_VER >= 20 |
78 | |
79 | _LIBCPP_END_NAMESPACE_STD |
80 | |
81 | #endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H |
82 | |