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