1*86df5a2fSLouis Dionne //===----------------------------------------------------------------------===//
2*86df5a2fSLouis Dionne //
3*86df5a2fSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*86df5a2fSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5*86df5a2fSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*86df5a2fSLouis Dionne //
7*86df5a2fSLouis Dionne //===----------------------------------------------------------------------===//
8*86df5a2fSLouis Dionne 
9*86df5a2fSLouis Dionne // UNSUPPORTED: c++03, c++11, c++14, c++17
10*86df5a2fSLouis Dionne // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11*86df5a2fSLouis Dionne 
12*86df5a2fSLouis Dionne // constexpr subrange() requires default_initializable<I>;
13*86df5a2fSLouis Dionne 
14*86df5a2fSLouis Dionne #include <ranges>
15*86df5a2fSLouis Dionne 
16*86df5a2fSLouis Dionne #include <cassert>
17*86df5a2fSLouis Dionne #include <cstddef>
18*86df5a2fSLouis Dionne 
19*86df5a2fSLouis Dionne #include "test_iterators.h"
20*86df5a2fSLouis Dionne 
21*86df5a2fSLouis Dionne // An input_or_output_iterator that is not default constructible so we can test
22*86df5a2fSLouis Dionne // the `requires` on subrange's default constructor.
23*86df5a2fSLouis Dionne struct NoDefaultIterator {
24*86df5a2fSLouis Dionne   using difference_type = std::ptrdiff_t;
25*86df5a2fSLouis Dionne   NoDefaultIterator() = delete;
26*86df5a2fSLouis Dionne   NoDefaultIterator& operator++();
27*86df5a2fSLouis Dionne   void operator++(int);
28*86df5a2fSLouis Dionne   int& operator*() const;
29*86df5a2fSLouis Dionne   friend bool operator==(NoDefaultIterator const&, NoDefaultIterator const&);
30*86df5a2fSLouis Dionne };
31*86df5a2fSLouis Dionne static_assert(std::input_or_output_iterator<NoDefaultIterator>);
32*86df5a2fSLouis Dionne 
33*86df5a2fSLouis Dionne // A sentinel type for the above iterator
34*86df5a2fSLouis Dionne struct Sentinel {
35*86df5a2fSLouis Dionne   friend bool operator==(NoDefaultIterator const&, Sentinel const&);
36*86df5a2fSLouis Dionne   friend bool operator==(Sentinel const&, NoDefaultIterator const&);
37*86df5a2fSLouis Dionne   friend bool operator!=(NoDefaultIterator const&, Sentinel const&);
38*86df5a2fSLouis Dionne   friend bool operator!=(Sentinel const&, NoDefaultIterator const&);
39*86df5a2fSLouis Dionne };
40*86df5a2fSLouis Dionne 
test()41*86df5a2fSLouis Dionne constexpr bool test() {
42*86df5a2fSLouis Dionne   {
43*86df5a2fSLouis Dionne     static_assert(!std::is_default_constructible_v<std::ranges::subrange<NoDefaultIterator, Sentinel, std::ranges::subrange_kind::sized>>);
44*86df5a2fSLouis Dionne     static_assert(!std::is_default_constructible_v<std::ranges::subrange<NoDefaultIterator, Sentinel, std::ranges::subrange_kind::unsized>>);
45*86df5a2fSLouis Dionne   }
46*86df5a2fSLouis Dionne 
47*86df5a2fSLouis Dionne   {
48*86df5a2fSLouis Dionne     using Iter = forward_iterator<int*>;
49*86df5a2fSLouis Dionne     std::ranges::subrange<Iter, Iter, std::ranges::subrange_kind::sized> subrange;
50*86df5a2fSLouis Dionne     assert(subrange.begin() == Iter());
51*86df5a2fSLouis Dionne     assert(subrange.end() == Iter());
52*86df5a2fSLouis Dionne   }
53*86df5a2fSLouis Dionne   {
54*86df5a2fSLouis Dionne     using Iter = forward_iterator<int*>;
55*86df5a2fSLouis Dionne     std::ranges::subrange<Iter, Iter, std::ranges::subrange_kind::unsized> subrange;
56*86df5a2fSLouis Dionne     assert(subrange.begin() == Iter());
57*86df5a2fSLouis Dionne     assert(subrange.end() == Iter());
58*86df5a2fSLouis Dionne   }
59*86df5a2fSLouis Dionne 
60*86df5a2fSLouis Dionne   return true;
61*86df5a2fSLouis Dionne }
62*86df5a2fSLouis Dionne 
main(int,char **)63*86df5a2fSLouis Dionne int main(int, char**) {
64*86df5a2fSLouis Dionne   test();
65*86df5a2fSLouis Dionne   static_assert(test());
66*86df5a2fSLouis Dionne 
67*86df5a2fSLouis Dionne   return 0;
68*86df5a2fSLouis Dionne }
69