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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11 
12 // constexpr auto begin();
13 // constexpr auto begin() const requires range<const V>;
14 
15 #include <ranges>
16 
17 #include <cassert>
18 #include <concepts>
19 #include <utility>
20 
21 #include "test_iterators.h"
22 #include "types.h"
23 
24 struct MutableView : std::ranges::view_base {
25   int* begin();
26   sentinel_wrapper<int*> end();
27 };
28 
29 template<class View>
30 concept BeginEnabled = requires(View v) { v.begin(); };
31 
test()32 constexpr bool test() {
33   int buf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
34 
35   {
36     static_assert( BeginEnabled<std::ranges::common_view<CopyableView> const&>);
37     static_assert( BeginEnabled<std::ranges::common_view<MutableView>&>);
38     static_assert(!BeginEnabled<std::ranges::common_view<MutableView> const&>);
39   }
40 
41   {
42     SizedRandomAccessView view{buf, buf + 8};
43     std::ranges::common_view<SizedRandomAccessView> common(view);
44     std::same_as<RandomAccessIter> auto begin = common.begin();
45     assert(begin == std::ranges::begin(view));
46   }
47 
48   {
49     SizedRandomAccessView view{buf, buf + 8};
50     std::ranges::common_view<SizedRandomAccessView> const common(view);
51     std::same_as<RandomAccessIter> auto begin = common.begin();
52     assert(begin == std::ranges::begin(view));
53   }
54 
55   return true;
56 }
57 
main(int,char **)58 int main(int, char**) {
59   test();
60   static_assert(test());
61 
62   // The non-constexpr tests:
63   int buf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
64 
65   {
66     SizedForwardView view{buf, buf + 8};
67     std::ranges::common_view<SizedForwardView> common(view);
68     using CommonIter = std::common_iterator<ForwardIter, sized_sentinel<ForwardIter>>;
69     std::same_as<CommonIter> auto begin = common.begin();
70     assert(begin == std::ranges::begin(view));
71     std::same_as<CommonIter> auto cbegin = std::as_const(common).begin();
72     assert(cbegin == std::ranges::begin(view));
73   }
74 
75   {
76     MoveOnlyView view{buf, buf + 8};
77     std::ranges::common_view<MoveOnlyView> common(std::move(view));
78     using CommonIter = std::common_iterator<int*, sentinel_wrapper<int*>>;
79     std::same_as<CommonIter> auto begin = common.begin();
80     assert(begin == std::ranges::begin(view));
81   }
82 
83   {
84     CopyableView view{buf, buf + 8};
85     std::ranges::common_view<CopyableView> const common(view);
86     using CommonIter = std::common_iterator<int*, sentinel_wrapper<int*>>;
87     std::same_as<CommonIter> auto begin = common.begin();
88     assert(begin == std::ranges::begin(view));
89   }
90 
91   return 0;
92 }
93