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