17b20e05cSzoecarver //===----------------------------------------------------------------------===//
27b20e05cSzoecarver //
37b20e05cSzoecarver // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47b20e05cSzoecarver // See https://llvm.org/LICENSE.txt for license information.
57b20e05cSzoecarver // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67b20e05cSzoecarver //
77b20e05cSzoecarver //===----------------------------------------------------------------------===//
87b20e05cSzoecarver
97b20e05cSzoecarver // UNSUPPORTED: c++03, c++11, c++14, c++17
107b20e05cSzoecarver // UNSUPPORTED: libcpp-has-no-incomplete-ranges
117b20e05cSzoecarver
127b20e05cSzoecarver // constexpr auto size() const requires see below;
137b20e05cSzoecarver
147b20e05cSzoecarver #include <ranges>
157b20e05cSzoecarver #include <cassert>
167b20e05cSzoecarver #include <limits>
177b20e05cSzoecarver
187b20e05cSzoecarver #include "test_macros.h"
197b20e05cSzoecarver #include "types.h"
207b20e05cSzoecarver
test()217b20e05cSzoecarver constexpr bool test() {
227b20e05cSzoecarver // Both are integer like and both are less than zero.
237b20e05cSzoecarver {
247b20e05cSzoecarver const std::ranges::iota_view<int, int> io(-10, -5);
257b20e05cSzoecarver assert(io.size() == 5);
267b20e05cSzoecarver }
277b20e05cSzoecarver {
287b20e05cSzoecarver const std::ranges::iota_view<int, int> io(-10, -10);
297b20e05cSzoecarver assert(io.size() == 0);
307b20e05cSzoecarver }
317b20e05cSzoecarver
327b20e05cSzoecarver // Both are integer like and "value_" is less than zero.
337b20e05cSzoecarver {
347b20e05cSzoecarver const std::ranges::iota_view<int, int> io(-10, 10);
357b20e05cSzoecarver assert(io.size() == 20);
367b20e05cSzoecarver }
377b20e05cSzoecarver {
387b20e05cSzoecarver // TODO: this is invalid with the current implementation. We need to file an LWG issue to
397b20e05cSzoecarver // fix this. Essentially the issue is: An int's min and max are -2147483648 and 2147483647
407b20e05cSzoecarver // which means the negated min cannot be represented as an integer; it needs to be cast to
417b20e05cSzoecarver // an unsigned type first. That seems to be what the
427b20e05cSzoecarver // to-unsigned-like(bound_) + to-unsigned-like(-value_))
437b20e05cSzoecarver // part of https://eel.is/c++draft/range.iota#view-15 is doing, but I think it's doing it
447b20e05cSzoecarver // wrong. It should be to-unsigned-like(bound_) - to-unsigned-like(value_)) (cast to
457b20e05cSzoecarver // unsigned first).
467b20e05cSzoecarver // const std::ranges::iota_view<int, int> io(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
477b20e05cSzoecarver // assert(io.size() == (static_cast<unsigned>(std::numeric_limits<int>::max()) * 2) + 1);
487b20e05cSzoecarver }
497b20e05cSzoecarver
507b20e05cSzoecarver // It is UB for "bound_" to be less than "value_" i.e.: iota_view<int, int> io(10, -5).
517b20e05cSzoecarver
527b20e05cSzoecarver // Both are integer like and neither less than zero.
537b20e05cSzoecarver {
547b20e05cSzoecarver const std::ranges::iota_view<int, int> io(10, 20);
557b20e05cSzoecarver assert(io.size() == 10);
567b20e05cSzoecarver }
577b20e05cSzoecarver {
587b20e05cSzoecarver const std::ranges::iota_view<int, int> io(10, 10);
597b20e05cSzoecarver assert(io.size() == 0);
607b20e05cSzoecarver }
617b20e05cSzoecarver {
627b20e05cSzoecarver const std::ranges::iota_view<int, int> io(0, 0);
637b20e05cSzoecarver assert(io.size() == 0);
647b20e05cSzoecarver }
657b20e05cSzoecarver {
667b20e05cSzoecarver const std::ranges::iota_view<int, int> io(0, std::numeric_limits<int>::max());
67*cb71d77cSCasey Carter constexpr auto imax = std::numeric_limits<int>::max();
68*cb71d77cSCasey Carter assert(io.size() == imax);
697b20e05cSzoecarver }
707b20e05cSzoecarver
717b20e05cSzoecarver // Neither are integer like.
727b20e05cSzoecarver {
737b20e05cSzoecarver const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(-20), SomeInt(-10));
747b20e05cSzoecarver assert(io.size() == 10);
757b20e05cSzoecarver }
767b20e05cSzoecarver {
777b20e05cSzoecarver const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(-10), SomeInt(-10));
787b20e05cSzoecarver assert(io.size() == 0);
797b20e05cSzoecarver }
807b20e05cSzoecarver {
817b20e05cSzoecarver const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(0), SomeInt(0));
827b20e05cSzoecarver assert(io.size() == 0);
837b20e05cSzoecarver }
847b20e05cSzoecarver {
857b20e05cSzoecarver const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(10), SomeInt(20));
867b20e05cSzoecarver assert(io.size() == 10);
877b20e05cSzoecarver }
887b20e05cSzoecarver {
897b20e05cSzoecarver const std::ranges::iota_view<SomeInt, SomeInt> io(SomeInt(10), SomeInt(10));
907b20e05cSzoecarver assert(io.size() == 0);
917b20e05cSzoecarver }
927b20e05cSzoecarver
937b20e05cSzoecarver return true;
947b20e05cSzoecarver }
957b20e05cSzoecarver
main(int,char **)967b20e05cSzoecarver int main(int, char**) {
977b20e05cSzoecarver test();
987b20e05cSzoecarver static_assert(test());
997b20e05cSzoecarver
1007b20e05cSzoecarver return 0;
1017b20e05cSzoecarver }
102