1*fe6060f1SDimitry Andric // -*- C++ -*- 2*fe6060f1SDimitry Andric //===--------------------- __ranges/concepts.h ----------------------------===// 3*fe6060f1SDimitry Andric // 4*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*fe6060f1SDimitry Andric // 8*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9*fe6060f1SDimitry Andric #ifndef _LIBCPP___RANGES_CONCEPTS_H 10*fe6060f1SDimitry Andric #define _LIBCPP___RANGES_CONCEPTS_H 11*fe6060f1SDimitry Andric 12*fe6060f1SDimitry Andric #include <__config> 13*fe6060f1SDimitry Andric #include <__iterator/concepts.h> 14*fe6060f1SDimitry Andric #include <__iterator/incrementable_traits.h> 15*fe6060f1SDimitry Andric #include <__iterator/iter_move.h> 16*fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 17*fe6060f1SDimitry Andric #include <__iterator/readable_traits.h> 18*fe6060f1SDimitry Andric #include <__ranges/access.h> 19*fe6060f1SDimitry Andric #include <__ranges/enable_borrowed_range.h> 20*fe6060f1SDimitry Andric #include <__ranges/data.h> 21*fe6060f1SDimitry Andric #include <__ranges/enable_view.h> 22*fe6060f1SDimitry Andric #include <__ranges/size.h> 23*fe6060f1SDimitry Andric #include <concepts> 24*fe6060f1SDimitry Andric #include <type_traits> 25*fe6060f1SDimitry Andric 26*fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 27*fe6060f1SDimitry Andric #pragma GCC system_header 28*fe6060f1SDimitry Andric #endif 29*fe6060f1SDimitry Andric 30*fe6060f1SDimitry Andric _LIBCPP_PUSH_MACROS 31*fe6060f1SDimitry Andric #include <__undef_macros> 32*fe6060f1SDimitry Andric 33*fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 34*fe6060f1SDimitry Andric 35*fe6060f1SDimitry Andric // clang-format off 36*fe6060f1SDimitry Andric 37*fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_RANGES) 38*fe6060f1SDimitry Andric 39*fe6060f1SDimitry Andric namespace ranges { 40*fe6060f1SDimitry Andric // [range.range] 41*fe6060f1SDimitry Andric template <class _Tp> 42*fe6060f1SDimitry Andric concept range = requires(_Tp& __t) { 43*fe6060f1SDimitry Andric ranges::begin(__t); // sometimes equality-preserving 44*fe6060f1SDimitry Andric ranges::end(__t); 45*fe6060f1SDimitry Andric }; 46*fe6060f1SDimitry Andric 47*fe6060f1SDimitry Andric template<class _Range> 48*fe6060f1SDimitry Andric concept borrowed_range = range<_Range> && 49*fe6060f1SDimitry Andric (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>); 50*fe6060f1SDimitry Andric 51*fe6060f1SDimitry Andric // `iterator_t` defined in <__ranges/access.h> 52*fe6060f1SDimitry Andric 53*fe6060f1SDimitry Andric template <range _Rp> 54*fe6060f1SDimitry Andric using sentinel_t = decltype(ranges::end(declval<_Rp&>())); 55*fe6060f1SDimitry Andric 56*fe6060f1SDimitry Andric template <range _Rp> 57*fe6060f1SDimitry Andric using range_difference_t = iter_difference_t<iterator_t<_Rp>>; 58*fe6060f1SDimitry Andric 59*fe6060f1SDimitry Andric template <range _Rp> 60*fe6060f1SDimitry Andric using range_value_t = iter_value_t<iterator_t<_Rp>>; 61*fe6060f1SDimitry Andric 62*fe6060f1SDimitry Andric template <range _Rp> 63*fe6060f1SDimitry Andric using range_reference_t = iter_reference_t<iterator_t<_Rp>>; 64*fe6060f1SDimitry Andric 65*fe6060f1SDimitry Andric template <range _Rp> 66*fe6060f1SDimitry Andric using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>; 67*fe6060f1SDimitry Andric 68*fe6060f1SDimitry Andric // [range.sized] 69*fe6060f1SDimitry Andric template <class _Tp> 70*fe6060f1SDimitry Andric concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; 71*fe6060f1SDimitry Andric 72*fe6060f1SDimitry Andric template<sized_range _Rp> 73*fe6060f1SDimitry Andric using range_size_t = decltype(ranges::size(declval<_Rp&>())); 74*fe6060f1SDimitry Andric 75*fe6060f1SDimitry Andric // `disable_sized_range` defined in `<__ranges/size.h>` 76*fe6060f1SDimitry Andric 77*fe6060f1SDimitry Andric // [range.view], views 78*fe6060f1SDimitry Andric 79*fe6060f1SDimitry Andric // `enable_view` defined in <__ranges/enable_view.h> 80*fe6060f1SDimitry Andric // `view_base` defined in <__ranges/enable_view.h> 81*fe6060f1SDimitry Andric 82*fe6060f1SDimitry Andric template <class _Tp> 83*fe6060f1SDimitry Andric concept view = 84*fe6060f1SDimitry Andric range<_Tp> && 85*fe6060f1SDimitry Andric movable<_Tp> && 86*fe6060f1SDimitry Andric enable_view<_Tp>; 87*fe6060f1SDimitry Andric 88*fe6060f1SDimitry Andric template<class _Range> 89*fe6060f1SDimitry Andric concept __simple_view = 90*fe6060f1SDimitry Andric view<_Range> && range<const _Range> && 91*fe6060f1SDimitry Andric same_as<iterator_t<_Range>, iterator_t<const _Range>> && 92*fe6060f1SDimitry Andric same_as<sentinel_t<_Range>, iterator_t<const _Range>>; 93*fe6060f1SDimitry Andric 94*fe6060f1SDimitry Andric // [range.refinements], other range refinements 95*fe6060f1SDimitry Andric template <class _Rp, class _Tp> 96*fe6060f1SDimitry Andric concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>; 97*fe6060f1SDimitry Andric 98*fe6060f1SDimitry Andric template <class _Tp> 99*fe6060f1SDimitry Andric concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>; 100*fe6060f1SDimitry Andric 101*fe6060f1SDimitry Andric template <class _Tp> 102*fe6060f1SDimitry Andric concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>; 103*fe6060f1SDimitry Andric 104*fe6060f1SDimitry Andric template <class _Tp> 105*fe6060f1SDimitry Andric concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>; 106*fe6060f1SDimitry Andric 107*fe6060f1SDimitry Andric template <class _Tp> 108*fe6060f1SDimitry Andric concept random_access_range = 109*fe6060f1SDimitry Andric bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>; 110*fe6060f1SDimitry Andric 111*fe6060f1SDimitry Andric template<class _Tp> 112*fe6060f1SDimitry Andric concept contiguous_range = 113*fe6060f1SDimitry Andric random_access_range<_Tp> && 114*fe6060f1SDimitry Andric contiguous_iterator<iterator_t<_Tp>> && 115*fe6060f1SDimitry Andric requires(_Tp& __t) { 116*fe6060f1SDimitry Andric { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>; 117*fe6060f1SDimitry Andric }; 118*fe6060f1SDimitry Andric 119*fe6060f1SDimitry Andric template <class _Tp> 120*fe6060f1SDimitry Andric concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; 121*fe6060f1SDimitry Andric 122*fe6060f1SDimitry Andric template<class _Tp> 123*fe6060f1SDimitry Andric concept viewable_range = 124*fe6060f1SDimitry Andric range<_Tp> && ( 125*fe6060f1SDimitry Andric (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || 126*fe6060f1SDimitry Andric (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>) 127*fe6060f1SDimitry Andric ); 128*fe6060f1SDimitry Andric } // namespace ranges 129*fe6060f1SDimitry Andric 130*fe6060f1SDimitry Andric #endif // !defined(_LIBCPP_HAS_NO_RANGES) 131*fe6060f1SDimitry Andric 132*fe6060f1SDimitry Andric // clang-format on 133*fe6060f1SDimitry Andric 134*fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 135*fe6060f1SDimitry Andric 136*fe6060f1SDimitry Andric _LIBCPP_POP_MACROS 137*fe6060f1SDimitry Andric 138*fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_CONCEPTS_H 139