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 <__config> 14 #include <concepts> 15 #include <type_traits> 16 17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 # pragma GCC system_header 19 #endif 20 21 _LIBCPP_BEGIN_NAMESPACE_STD 22 23 #if _LIBCPP_STD_VER > 17 24 25 // [readable.traits] 26 template<class> struct __cond_value_type {}; 27 28 template<class _Tp> 29 requires is_object_v<_Tp> 30 struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; 31 32 template<class _Tp> 33 concept __has_member_value_type = requires { typename _Tp::value_type; }; 34 35 template<class _Tp> 36 concept __has_member_element_type = requires { typename _Tp::element_type; }; 37 38 template<class> struct indirectly_readable_traits {}; 39 40 template<class _Ip> 41 requires is_array_v<_Ip> 42 struct indirectly_readable_traits<_Ip> { 43 using value_type = remove_cv_t<remove_extent_t<_Ip>>; 44 }; 45 46 template<class _Ip> 47 struct indirectly_readable_traits<const _Ip> : indirectly_readable_traits<_Ip> {}; 48 49 template<class _Tp> 50 struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; 51 52 template<__has_member_value_type _Tp> 53 struct indirectly_readable_traits<_Tp> 54 : __cond_value_type<typename _Tp::value_type> {}; 55 56 template<__has_member_element_type _Tp> 57 struct indirectly_readable_traits<_Tp> 58 : __cond_value_type<typename _Tp::element_type> {}; 59 60 template<__has_member_value_type _Tp> 61 requires __has_member_element_type<_Tp> 62 struct indirectly_readable_traits<_Tp> {}; 63 64 template<__has_member_value_type _Tp> 65 requires __has_member_element_type<_Tp> && 66 same_as<remove_cv_t<typename _Tp::element_type>, 67 remove_cv_t<typename _Tp::value_type>> 68 struct indirectly_readable_traits<_Tp> 69 : __cond_value_type<typename _Tp::value_type> {}; 70 71 template <class> 72 struct iterator_traits; 73 74 // Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes 75 // `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization 76 // generated from the primary template, and `iterator_traits<RI>::value_type` otherwise. 77 template <class _Ip> 78 using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value, 79 indirectly_readable_traits<remove_cvref_t<_Ip> >, 80 iterator_traits<remove_cvref_t<_Ip> > >::value_type; 81 82 #endif // _LIBCPP_STD_VER > 17 83 84 _LIBCPP_END_NAMESPACE_STD 85 86 #endif // _LIBCPP___ITERATOR_READABLE_TRAITS_H 87