xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/ctor.base.pass.cpp (revision a2c6a1193f41e40840a7ead6c1c0540d3062c13a)
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 
11 // constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred);
12 
13 #include <cassert>
14 #include <ranges>
15 #include <utility>
16 
17 #include "../types.h"
18 
19 struct Sent {
20   int i;
21 
operator ==(int * iter,const Sent & s)22   friend constexpr bool operator==(int* iter, const Sent& s) { return s.i > *iter; }
23 };
24 
25 struct Range : std::ranges::view_base {
26   int* begin() const;
27   Sent end();
28 };
29 
30 struct Pred {
31   bool operator()(int i) const;
32 };
33 
34 // Test explicit
35 template <class T>
36 void conversion_test(T);
37 
38 template <class T, class... Args>
39 concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
40 static_assert(ImplicitlyConstructible<int, int>);
41 
42 static_assert(std::is_constructible_v<std::ranges::sentinel_t<std::ranges::take_while_view<Range, Pred>>,
43                                       std::ranges::sentinel_t<Range>,
44                                       const Pred*>);
45 static_assert(!ImplicitlyConstructible<std::ranges::sentinel_t<std::ranges::take_while_view<Range, Pred>>,
46                                        std::ranges::sentinel_t<Range>,
47                                        const Pred*>);
48 
test()49 constexpr bool test() {
50   // base is init correctly
51   {
52     using R        = std::ranges::take_while_view<Range, bool (*)(int)>;
53     using Sentinel = std::ranges::sentinel_t<R>;
54 
55     Sentinel s1(Sent{5}, nullptr);
56     assert(s1.base().i == 5);
57   }
58 
59   // pred is init correctly
60   {
61     bool called = false;
62     auto pred   = [&](int) {
63       called = true;
64       return false;
65     };
66 
67     using R        = std::ranges::take_while_view<Range, decltype(pred)>;
68     using Sentinel = std::ranges::sentinel_t<R>;
69 
70     int i     = 10;
71     int* iter = &i;
72     Sentinel s(Sent{0}, &pred);
73 
74     bool b = iter == s;
75     assert(called);
76     assert(b);
77   }
78   return true;
79 }
80 
main(int,char **)81 int main(int, char**) {
82   test();
83   static_assert(test());
84 
85   return 0;
86 }
87