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___RANGES_CONCEPTS_H 11#define _LIBCPP___RANGES_CONCEPTS_H 12 13#include <__concepts/constructible.h> 14#include <__concepts/movable.h> 15#include <__concepts/same_as.h> 16#include <__config> 17#include <__iterator/concepts.h> 18#include <__iterator/incrementable_traits.h> 19#include <__iterator/iter_move.h> 20#include <__iterator/iterator_traits.h> 21#include <__iterator/readable_traits.h> 22#include <__ranges/access.h> 23#include <__ranges/data.h> 24#include <__ranges/enable_borrowed_range.h> 25#include <__ranges/enable_view.h> 26#include <__ranges/size.h> 27#include <__type_traits/add_pointer.h> 28#include <__type_traits/is_reference.h> 29#include <__type_traits/remove_cvref.h> 30#include <__type_traits/remove_reference.h> 31#include <__utility/declval.h> 32#include <initializer_list> 33 34#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 35# pragma GCC system_header 36#endif 37 38_LIBCPP_BEGIN_NAMESPACE_STD 39 40#if _LIBCPP_STD_VER >= 20 41 42namespace ranges { 43 44// [range.range] 45 46template <class _Tp> 47concept range = requires(_Tp& __t) { 48 ranges::begin(__t); // sometimes equality-preserving 49 ranges::end(__t); 50}; 51 52template <class _Tp> 53concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>; 54 55template <class _Range> 56concept borrowed_range = 57 range<_Range> && (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>); 58 59// `iterator_t` defined in <__ranges/access.h> 60 61template <range _Rp> 62using sentinel_t = decltype(ranges::end(std::declval<_Rp&>())); 63 64template <range _Rp> 65using range_difference_t = iter_difference_t<iterator_t<_Rp>>; 66 67template <range _Rp> 68using range_value_t = iter_value_t<iterator_t<_Rp>>; 69 70template <range _Rp> 71using range_reference_t = iter_reference_t<iterator_t<_Rp>>; 72 73template <range _Rp> 74using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>; 75 76template <range _Rp> 77using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>; 78 79// [range.sized] 80template <class _Tp> 81concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; 82 83template <sized_range _Rp> 84using range_size_t = decltype(ranges::size(std::declval<_Rp&>())); 85 86// `disable_sized_range` defined in `<__ranges/size.h>` 87 88// [range.view], views 89 90// `enable_view` defined in <__ranges/enable_view.h> 91// `view_base` defined in <__ranges/enable_view.h> 92 93template <class _Tp> 94concept view = range<_Tp> && movable<_Tp> && enable_view<_Tp>; 95 96template <class _Range> 97concept __simple_view = 98 view<_Range> && range<const _Range> && same_as<iterator_t<_Range>, iterator_t<const _Range>> && 99 same_as<sentinel_t<_Range>, sentinel_t<const _Range>>; 100 101// [range.refinements], other range refinements 102template <class _Rp, class _Tp> 103concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>; 104 105template <class _Tp> 106concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>; 107 108template <class _Tp> 109concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>; 110 111template <class _Tp> 112concept random_access_range = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>; 113 114template <class _Tp> 115concept contiguous_range = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>> && requires(_Tp& __t) { 116 { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>; 117}; 118 119template <class _Tp> 120concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; 121 122template <class _Tp> 123inline constexpr bool __is_std_initializer_list = false; 124 125template <class _Ep> 126inline constexpr bool __is_std_initializer_list<initializer_list<_Ep>> = true; 127 128template <class _Tp> 129concept viewable_range = 130 range<_Tp> && 131 ((view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || 132 (!view<remove_cvref_t<_Tp>> && 133 (is_lvalue_reference_v<_Tp> || 134 (movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>)))); 135 136} // namespace ranges 137 138#endif // _LIBCPP_STD_VER >= 20 139 140_LIBCPP_END_NAMESPACE_STD 141 142#endif // _LIBCPP___RANGES_CONCEPTS_H 143