1e5d8b93eSzoecarver //===----------------------------------------------------------------------===//
2e5d8b93eSzoecarver //
3e5d8b93eSzoecarver // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5d8b93eSzoecarver // See https://llvm.org/LICENSE.txt for license information.
5e5d8b93eSzoecarver // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5d8b93eSzoecarver //
7e5d8b93eSzoecarver //===----------------------------------------------------------------------===//
8e5d8b93eSzoecarver
9e5d8b93eSzoecarver // UNSUPPORTED: c++03, c++11, c++14, c++17
10e5d8b93eSzoecarver
11e5d8b93eSzoecarver // constexpr auto begin();
12e5d8b93eSzoecarver // constexpr auto begin() const requires range<const V>;
13e5d8b93eSzoecarver
14e5d8b93eSzoecarver #include <ranges>
1503fb6f04SLouis Dionne
16e5d8b93eSzoecarver #include <cassert>
1703fb6f04SLouis Dionne #include <concepts>
1803fb6f04SLouis Dionne #include <utility>
19e5d8b93eSzoecarver
20e5d8b93eSzoecarver #include "test_iterators.h"
2103fb6f04SLouis Dionne #include "types.h"
22e5d8b93eSzoecarver
23e5d8b93eSzoecarver struct MutableView : std::ranges::view_base {
2403fb6f04SLouis Dionne int* begin();
2503fb6f04SLouis Dionne sentinel_wrapper<int*> end();
26e5d8b93eSzoecarver };
27e5d8b93eSzoecarver
2803fb6f04SLouis Dionne template<class View>
2903fb6f04SLouis Dionne concept BeginEnabled = requires(View v) { v.begin(); };
30e5d8b93eSzoecarver
test()31e5d8b93eSzoecarver constexpr bool test() {
3203fb6f04SLouis Dionne int buf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
33e5d8b93eSzoecarver
34e5d8b93eSzoecarver {
3503fb6f04SLouis Dionne static_assert( BeginEnabled<std::ranges::common_view<CopyableView> const&>);
3603fb6f04SLouis Dionne static_assert( BeginEnabled<std::ranges::common_view<MutableView>&>);
3703fb6f04SLouis Dionne static_assert(!BeginEnabled<std::ranges::common_view<MutableView> const&>);
38e5d8b93eSzoecarver }
39e5d8b93eSzoecarver
40e5d8b93eSzoecarver {
4103fb6f04SLouis Dionne SizedRandomAccessView view{buf, buf + 8};
4203fb6f04SLouis Dionne std::ranges::common_view<SizedRandomAccessView> common(view);
4303fb6f04SLouis Dionne std::same_as<RandomAccessIter> auto begin = common.begin();
4403fb6f04SLouis Dionne assert(begin == std::ranges::begin(view));
45e5d8b93eSzoecarver }
46e5d8b93eSzoecarver
47e5d8b93eSzoecarver {
4803fb6f04SLouis Dionne SizedRandomAccessView view{buf, buf + 8};
4903fb6f04SLouis Dionne std::ranges::common_view<SizedRandomAccessView> const common(view);
5003fb6f04SLouis Dionne std::same_as<RandomAccessIter> auto begin = common.begin();
5103fb6f04SLouis Dionne assert(begin == std::ranges::begin(view));
52e5d8b93eSzoecarver }
53e5d8b93eSzoecarver
54e5d8b93eSzoecarver return true;
55e5d8b93eSzoecarver }
56e5d8b93eSzoecarver
main(int,char **)57e5d8b93eSzoecarver int main(int, char**) {
58e5d8b93eSzoecarver test();
59e5d8b93eSzoecarver static_assert(test());
60e5d8b93eSzoecarver
61e5d8b93eSzoecarver // The non-constexpr tests:
6203fb6f04SLouis Dionne int buf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
63e5d8b93eSzoecarver
64e5d8b93eSzoecarver {
6503fb6f04SLouis Dionne SizedForwardView view{buf, buf + 8};
6603fb6f04SLouis Dionne std::ranges::common_view<SizedForwardView> common(view);
672a04deccSArthur O'Dwyer using CommonIter = std::common_iterator<ForwardIter, sized_sentinel<ForwardIter>>;
6803fb6f04SLouis Dionne std::same_as<CommonIter> auto begin = common.begin();
6903fb6f04SLouis Dionne assert(begin == std::ranges::begin(view));
70*1fe897dfSArthur O'Dwyer std::same_as<CommonIter> auto cbegin = std::as_const(common).begin();
71*1fe897dfSArthur O'Dwyer assert(cbegin == std::ranges::begin(view));
72e5d8b93eSzoecarver }
73e5d8b93eSzoecarver
74e5d8b93eSzoecarver {
75610ac8dbSArthur O'Dwyer MoveOnlyView view{buf, buf + 8};
76610ac8dbSArthur O'Dwyer std::ranges::common_view<MoveOnlyView> common(std::move(view));
7703fb6f04SLouis Dionne using CommonIter = std::common_iterator<int*, sentinel_wrapper<int*>>;
7803fb6f04SLouis Dionne std::same_as<CommonIter> auto begin = common.begin();
7903fb6f04SLouis Dionne assert(begin == std::ranges::begin(view));
80e5d8b93eSzoecarver }
81e5d8b93eSzoecarver
82e5d8b93eSzoecarver {
8303fb6f04SLouis Dionne CopyableView view{buf, buf + 8};
8403fb6f04SLouis Dionne std::ranges::common_view<CopyableView> const common(view);
8503fb6f04SLouis Dionne using CommonIter = std::common_iterator<int*, sentinel_wrapper<int*>>;
8603fb6f04SLouis Dionne std::same_as<CommonIter> auto begin = common.begin();
8703fb6f04SLouis Dionne assert(begin == std::ranges::begin(view));
88e5d8b93eSzoecarver }
89e5d8b93eSzoecarver
90e5d8b93eSzoecarver return 0;
91e5d8b93eSzoecarver }
92