File indexing completed on 2026-05-03 08:14:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___RANGES_SIZE_H
0011 #define _LIBCPP___RANGES_SIZE_H
0012
0013 #include <__concepts/arithmetic.h>
0014 #include <__concepts/class_or_enum.h>
0015 #include <__config>
0016 #include <__cstddef/ptrdiff_t.h>
0017 #include <__cstddef/size_t.h>
0018 #include <__iterator/concepts.h>
0019 #include <__iterator/iterator_traits.h>
0020 #include <__ranges/access.h>
0021 #include <__type_traits/decay.h>
0022 #include <__type_traits/make_signed.h>
0023 #include <__type_traits/make_unsigned.h>
0024 #include <__type_traits/remove_cvref.h>
0025 #include <__utility/auto_cast.h>
0026 #include <__utility/declval.h>
0027
0028 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0029 # pragma GCC system_header
0030 #endif
0031
0032 _LIBCPP_BEGIN_NAMESPACE_STD
0033
0034 #if _LIBCPP_STD_VER >= 20
0035
0036 namespace ranges {
0037 template <class>
0038 inline constexpr bool disable_sized_range = false;
0039 }
0040
0041
0042
0043 namespace ranges {
0044 namespace __size {
0045 void size() = delete;
0046
0047 template <class _Tp>
0048 concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
0049
0050 template <class _Tp>
0051 concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) {
0052 { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
0053 };
0054
0055 template <class _Tp>
0056 concept __unqualified_size =
0057 __size_enabled<_Tp> && !__member_size<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
0058 { _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
0059 };
0060
0061 template <class _Tp>
0062 concept __difference =
0063 !__member_size<_Tp> && !__unqualified_size<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
0064 { ranges::begin(__t) } -> forward_iterator;
0065 { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(std::declval<_Tp>()))>;
0066 };
0067
0068 struct __fn {
0069
0070 template <class _Tp, size_t _Sz>
0071 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
0072 return _Sz;
0073 }
0074
0075
0076 template <class _Tp, size_t _Sz>
0077 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
0078 return _Sz;
0079 }
0080
0081
0082 template <__member_size _Tp>
0083 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
0084 noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {
0085 return _LIBCPP_AUTO_CAST(__t.size());
0086 }
0087
0088
0089 template <__unqualified_size _Tp>
0090 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
0091 noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {
0092 return _LIBCPP_AUTO_CAST(size(__t));
0093 }
0094
0095
0096 template <__difference _Tp>
0097 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
0098 noexcept(noexcept(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))))
0099 -> decltype(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))) {
0100 return std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
0101 }
0102 };
0103
0104 }
0105
0106 inline namespace __cpo {
0107 inline constexpr auto size = __size::__fn{};
0108 }
0109 }
0110
0111
0112
0113 namespace ranges {
0114 namespace __ssize {
0115 struct __fn {
0116 template <class _Tp>
0117 requires requires(_Tp&& __t) { ranges::size(__t); }
0118 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
0119 noexcept(noexcept(ranges::size(__t))) {
0120 using _Signed = make_signed_t<decltype(ranges::size(__t))>;
0121 if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
0122 return static_cast<ptrdiff_t>(ranges::size(__t));
0123 else
0124 return static_cast<_Signed>(ranges::size(__t));
0125 }
0126 };
0127 }
0128
0129 inline namespace __cpo {
0130 inline constexpr auto ssize = __ssize::__fn{};
0131 }
0132 }
0133
0134 #endif
0135
0136 _LIBCPP_END_NAMESPACE_STD
0137
0138 #endif