xref: /llvm-project/libcxx/include/__ranges/concepts.h (revision 9783f28cbb155e4a8d49c12e1c60ce14dcfaf0c7)
17c177315SChristopher Di Bella // -*- C++ -*-
2eb8650a7SLouis Dionne //===----------------------------------------------------------------------===//
37c177315SChristopher Di Bella //
47c177315SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
57c177315SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
67c177315SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
77c177315SChristopher Di Bella //
87c177315SChristopher Di Bella //===----------------------------------------------------------------------===//
9480cd780SLouis Dionne 
10d8fad661SChristopher Di Bella #ifndef _LIBCPP___RANGES_CONCEPTS_H
11d8fad661SChristopher Di Bella #define _LIBCPP___RANGES_CONCEPTS_H
127c177315SChristopher Di Bella 
1367151d02SArthur O'Dwyer #include <__concepts/constructible.h>
1467151d02SArthur O'Dwyer #include <__concepts/movable.h>
1567151d02SArthur O'Dwyer #include <__concepts/same_as.h>
167c177315SChristopher Di Bella #include <__config>
17d8fad661SChristopher Di Bella #include <__iterator/concepts.h>
18332da1c2SChristopher Di Bella #include <__iterator/incrementable_traits.h>
19332da1c2SChristopher Di Bella #include <__iterator/iter_move.h>
20332da1c2SChristopher Di Bella #include <__iterator/iterator_traits.h>
21332da1c2SChristopher Di Bella #include <__iterator/readable_traits.h>
22d8fad661SChristopher Di Bella #include <__ranges/access.h>
2334503987Szoecarver #include <__ranges/data.h>
24a60b6394SJoe Loser #include <__ranges/enable_borrowed_range.h>
25bbb3d03fSChristopher Di Bella #include <__ranges/enable_view.h>
26d8fad661SChristopher Di Bella #include <__ranges/size.h>
27e0a66116SNikolas Klauser #include <__type_traits/add_pointer.h>
28e0a66116SNikolas Klauser #include <__type_traits/is_reference.h>
29e0a66116SNikolas Klauser #include <__type_traits/remove_cvref.h>
30e0a66116SNikolas Klauser #include <__type_traits/remove_reference.h>
31e0a66116SNikolas Klauser #include <__utility/declval.h>
3267151d02SArthur O'Dwyer #include <initializer_list>
337c177315SChristopher Di Bella 
347c177315SChristopher Di Bella #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
357c177315SChristopher Di Bella #  pragma GCC system_header
367c177315SChristopher Di Bella #endif
377c177315SChristopher Di Bella 
387c177315SChristopher Di Bella _LIBCPP_BEGIN_NAMESPACE_STD
397c177315SChristopher Di Bella 
404f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20
417c177315SChristopher Di Bella 
427c177315SChristopher Di Bella namespace ranges {
4353406fb6SArthur O'Dwyer 
447c177315SChristopher Di Bella // [range.range]
4553406fb6SArthur O'Dwyer 
467c177315SChristopher Di Bella template <class _Tp>
requires(_Tp & __t)477c177315SChristopher Di Bella concept range = requires(_Tp& __t) {
487c177315SChristopher Di Bella   ranges::begin(__t); // sometimes equality-preserving
497c177315SChristopher Di Bella   ranges::end(__t);
507c177315SChristopher Di Bella };
517c177315SChristopher Di Bella 
5253406fb6SArthur O'Dwyer template <class _Tp>
5353406fb6SArthur O'Dwyer concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
5453406fb6SArthur O'Dwyer 
55c40b0260Szoecarver template <class _Range>
56*9783f28cSLouis Dionne concept borrowed_range =
57*9783f28cSLouis Dionne     range<_Range> && (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>);
58c40b0260Szoecarver 
597e9cf207SArthur O'Dwyer // `iterator_t` defined in <__ranges/access.h>
607c177315SChristopher Di Bella 
617c177315SChristopher Di Bella template <range _Rp>
6273e8e1baSNikolas Klauser using sentinel_t = decltype(ranges::end(std::declval<_Rp&>()));
637c177315SChristopher Di Bella 
647c177315SChristopher Di Bella template <range _Rp>
657c177315SChristopher Di Bella using range_difference_t = iter_difference_t<iterator_t<_Rp>>;
667c177315SChristopher Di Bella 
677c177315SChristopher Di Bella template <range _Rp>
687c177315SChristopher Di Bella using range_value_t = iter_value_t<iterator_t<_Rp>>;
697c177315SChristopher Di Bella 
707c177315SChristopher Di Bella template <range _Rp>
717c177315SChristopher Di Bella using range_reference_t = iter_reference_t<iterator_t<_Rp>>;
727c177315SChristopher Di Bella 
737c177315SChristopher Di Bella template <range _Rp>
747c177315SChristopher Di Bella using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
757c177315SChristopher Di Bella 
76a8ead919SIgor Zhukov template <range _Rp>
77a8ead919SIgor Zhukov using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>;
78a8ead919SIgor Zhukov 
79d8fad661SChristopher Di Bella // [range.sized]
80d8fad661SChristopher Di Bella template <class _Tp>
requires(_Tp & __t)81d8fad661SChristopher Di Bella concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
82d8fad661SChristopher Di Bella 
83fbaf7f0bSLouis Dionne template <sized_range _Rp>
8473e8e1baSNikolas Klauser using range_size_t = decltype(ranges::size(std::declval<_Rp&>()));
85fbaf7f0bSLouis Dionne 
86d8fad661SChristopher Di Bella // `disable_sized_range` defined in `<__ranges/size.h>`
87d8fad661SChristopher Di Bella 
88bbb3d03fSChristopher Di Bella // [range.view], views
89bbb3d03fSChristopher Di Bella 
90bbb3d03fSChristopher Di Bella // `enable_view` defined in <__ranges/enable_view.h>
91bbb3d03fSChristopher Di Bella // `view_base` defined in <__ranges/enable_view.h>
92bbb3d03fSChristopher Di Bella 
93bbb3d03fSChristopher Di Bella template <class _Tp>
94*9783f28cSLouis Dionne concept view = range<_Tp> && movable<_Tp> && enable_view<_Tp>;
95bbb3d03fSChristopher Di Bella 
96bbb3d03fSChristopher Di Bella template <class _Range>
97bbb3d03fSChristopher Di Bella concept __simple_view =
98*9783f28cSLouis Dionne     view<_Range> && range<const _Range> && same_as<iterator_t<_Range>, iterator_t<const _Range>> &&
99597b90ebSHui Xie     same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
100bbb3d03fSChristopher Di Bella 
1017c177315SChristopher Di Bella // [range.refinements], other range refinements
1027b28c5d3SLouis Dionne template <class _Rp, class _Tp>
1037b28c5d3SLouis Dionne concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>;
1047b28c5d3SLouis Dionne 
1057c177315SChristopher Di Bella template <class _Tp>
106fa3e2626SChristopher Di Bella concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
107fa3e2626SChristopher Di Bella 
108fa3e2626SChristopher Di Bella template <class _Tp>
1099c5d86aaSChristopher Di Bella concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
110fa3e2626SChristopher Di Bella 
1119c5d86aaSChristopher Di Bella template <class _Tp>
112*9783f28cSLouis Dionne concept random_access_range = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
113d8fad661SChristopher Di Bella 
114d8fad661SChristopher Di Bella template <class _Tp>
requires(_Tp & __t)115*9783f28cSLouis Dionne concept contiguous_range = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>> && requires(_Tp& __t) {
11634503987Szoecarver   { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
11734503987Szoecarver };
11834503987Szoecarver 
11934503987Szoecarver template <class _Tp>
120d8fad661SChristopher Di Bella concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
1213001b48dSLouis Dionne 
1223001b48dSLouis Dionne template <class _Tp>
12367151d02SArthur O'Dwyer inline constexpr bool __is_std_initializer_list = false;
12467151d02SArthur O'Dwyer 
12567151d02SArthur O'Dwyer template <class _Ep>
12667151d02SArthur O'Dwyer inline constexpr bool __is_std_initializer_list<initializer_list<_Ep>> = true;
12767151d02SArthur O'Dwyer 
12867151d02SArthur O'Dwyer template <class _Tp>
1293001b48dSLouis Dionne concept viewable_range =
13067151d02SArthur O'Dwyer     range<_Tp> &&
13167151d02SArthur O'Dwyer     ((view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) ||
13267151d02SArthur O'Dwyer      (!view<remove_cvref_t<_Tp>> &&
13367151d02SArthur O'Dwyer       (is_lvalue_reference_v<_Tp> ||
13467151d02SArthur O'Dwyer        (movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>))));
13567151d02SArthur O'Dwyer 
1367c177315SChristopher Di Bella } // namespace ranges
1377c177315SChristopher Di Bella 
1384f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20
1397c177315SChristopher Di Bella 
1407c177315SChristopher Di Bella _LIBCPP_END_NAMESPACE_STD
1417c177315SChristopher Di Bella 
142d8fad661SChristopher Di Bella #endif // _LIBCPP___RANGES_CONCEPTS_H
143