Path: blob/main/contrib/llvm-project/libcxx/include/__ranges/size.h
35236 views
// -*- C++ -*-1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___RANGES_SIZE_H10#define _LIBCPP___RANGES_SIZE_H1112#include <__concepts/arithmetic.h>13#include <__concepts/class_or_enum.h>14#include <__config>15#include <__iterator/concepts.h>16#include <__iterator/iterator_traits.h>17#include <__ranges/access.h>18#include <__type_traits/decay.h>19#include <__type_traits/make_signed.h>20#include <__type_traits/make_unsigned.h>21#include <__type_traits/remove_cvref.h>22#include <__utility/auto_cast.h>23#include <__utility/declval.h>24#include <cstddef>2526#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)27# pragma GCC system_header28#endif2930_LIBCPP_BEGIN_NAMESPACE_STD3132#if _LIBCPP_STD_VER >= 203334namespace ranges {35template <class>36inline constexpr bool disable_sized_range = false;37} // namespace ranges3839// [range.prim.size]4041namespace ranges {42namespace __size {43void size() = delete;4445template <class _Tp>46concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;4748template <class _Tp>49concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) {50{ _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;51};5253template <class _Tp>54concept __unqualified_size =55__size_enabled<_Tp> && !__member_size<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {56{ _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;57};5859template <class _Tp>60concept __difference =61!__member_size<_Tp> && !__unqualified_size<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {62{ ranges::begin(__t) } -> forward_iterator;63{ ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(std::declval<_Tp>()))>;64};6566struct __fn {67// `[range.prim.size]`: the array case (for rvalues).68template <class _Tp, size_t _Sz>69[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {70return _Sz;71}7273// `[range.prim.size]`: the array case (for lvalues).74template <class _Tp, size_t _Sz>75[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {76return _Sz;77}7879// `[range.prim.size]`: `auto(t.size())` is a valid expression.80template <__member_size _Tp>81[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const82noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {83return _LIBCPP_AUTO_CAST(__t.size());84}8586// `[range.prim.size]`: `auto(size(t))` is a valid expression.87template <__unqualified_size _Tp>88[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const89noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {90return _LIBCPP_AUTO_CAST(size(__t));91}9293// [range.prim.size]: the `to-unsigned-like` case.94template <__difference _Tp>95[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const96noexcept(noexcept(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))))97-> decltype(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))) {98return std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));99}100};101102} // namespace __size103104inline namespace __cpo {105inline constexpr auto size = __size::__fn{};106} // namespace __cpo107} // namespace ranges108109// [range.prim.ssize]110111namespace ranges {112namespace __ssize {113struct __fn {114template <class _Tp>115requires requires(_Tp&& __t) { ranges::size(__t); }116[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const117noexcept(noexcept(ranges::size(__t))) {118using _Signed = make_signed_t<decltype(ranges::size(__t))>;119if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))120return static_cast<ptrdiff_t>(ranges::size(__t));121else122return static_cast<_Signed>(ranges::size(__t));123}124};125} // namespace __ssize126127inline namespace __cpo {128inline constexpr auto ssize = __ssize::__fn{};129} // namespace __cpo130} // namespace ranges131132#endif // _LIBCPP_STD_VER >= 20133134_LIBCPP_END_NAMESPACE_STD135136#endif // _LIBCPP___RANGES_SIZE_H137138139