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 auto size() const requires see below;
12
13#include <cassert>
14#include <concepts>
15#include <limits>
16#include <ranges>
17
18#include "test_macros.h"
19#include "types.h"
20
21constexpr bool test() {
22 // Both are integer like and both are less than zero.
23 {
24 const std::ranges::iota_view<int, int> io(-10, -5);
25 assert(io.size() == 5);
26 }
27 {
28 const std::ranges::iota_view<int, int> io(-10, -10);
29 assert(io.size() == 0);
30 }
31
32 // Both are integer like and "value_" is less than zero.
33 {
34 const std::ranges::iota_view<int, int> io(-10, 10);
35 assert(io.size() == 20);
36 }
37 {
38// TODO: this is invalid with the current implementation. We need to file an LWG issue to
39// fix this. Essentially the issue is: An int's min and max are -2147483648 and 2147483647
40// which means the negated min cannot be represented as an integer; it needs to be cast to
41// an unsigned type first. That seems to be what the
42// to-unsigned-like(bound_) + to-unsigned-like(-value_))
43// part of https://eel.is/c++draft/range.iota#view-15 is doing, but I think it's doing it
44// wrong. It should be to-unsigned-like(bound_) - to-unsigned-like(value_)) (cast to
45// unsigned first).
46// const std::ranges::iota_view<int, int> io(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
47// assert(io.size() == (static_cast<unsigned>(std::numeric_limits<int>::max()) * 2) + 1);
48 }
49
50 // It is UB for "bound_" to be less than "value_" i.e.: iota_view<int, int> io(10, -5).
51
52 // Both are integer like and neither less than zero.
53 {
54 const std::ranges::iota_view<int, int> io(10, 20);
55 assert(io.size() == 10);
56 }
57 {
58 const std::ranges::iota_view<int, int> io(10, 10);
59 assert(io.size() == 0);
60 }
61 {
62 const std::ranges::iota_view<int, int> io(0, 0);
63 assert(io.size() == 0);
64 }
65 {
66 const std::ranges::iota_view<int, int> io(0, std::numeric_limits<int>::max());
67 constexpr auto imax = std::numeric_limits<int>::max();
68 assert(io.size() == imax);
69 }
70
71 // Neither are integer like.
72 {
73 const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(-20), SomeInt(-10));
74 assert(io.size() == 10);
75 }
76 {
77 const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(-10), SomeInt(-10));
78 assert(io.size() == 0);
79 }
80 {
81 const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(0), SomeInt(0));
82 assert(io.size() == 0);
83 }
84 {
85 const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(10), SomeInt(20));
86 assert(io.size() == 10);
87 }
88 {
89 const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(10), SomeInt(10));
90 assert(io.size() == 0);
91 }
92
93 // Make sure iota_view<short, short> works properly. For details,
94 // see https://github.com/llvm/llvm-project/issues/67551.
95 {
96 static_assert(std::ranges::sized_range<std::ranges::iota_view<short, short>>);
97 std::ranges::iota_view<short, short> io(10, 20);
98 std::same_as<unsigned int> auto sz = io.size();
99 assert(sz == 10);
100 }
101
102 return true;
103}
104
105int main(int, char**) {
106 test();
107 static_assert(test());
108
109 return 0;
110}
111

source code of libcxx/test/std/ranges/range.factories/range.iota.view/size.pass.cpp