111 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 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 to39// fix this. Essentially the issue is: An int's min and max are -2147483648 and 214748364740// which means the negated min cannot be represented as an integer; it needs to be cast to41// an unsigned type first. That seems to be what the42// 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 it44// wrong. It should be to-unsigned-like(bound_) - to-unsigned-like(value_)) (cast to45// 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://llvm.org/PR67551.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