//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 // constexpr iterator& operator--() requires bidirectional_range; // constexpr iterator operator--(int) requires bidirectional_range; #include #include #include #include #include "test_iterators.h" template concept CanPreDecrement = requires(Iter it) { --it; }; template concept CanPostDecrement = requires(Iter it) { it--; }; template > constexpr void testOne() { using Range = std::ranges::subrange; std::tuple ts[] = {{1}, {2}, {3}}; auto ev = Range{Iter{&ts[0]}, Sent{Iter{&ts[0] + 3}}} | std::views::elements<0>; using ElementIter = std::ranges::iterator_t; if constexpr (!std::bidirectional_iterator) { auto it = ev.begin(); static_assert(!CanPreDecrement); static_assert(!CanPostDecrement); } else { // --i { auto it = ev.begin(); static_assert(CanPreDecrement); ++it; assert(base(it.base()) == &ts[1]); decltype(auto) result = --it; static_assert(std::is_same_v); assert(&result == &it); assert(base(it.base()) == &ts[0]); } // i-- { auto it = ev.begin(); static_assert(CanPostDecrement); ++it; assert(base(it.base()) == &ts[1]); decltype(auto) result = it--; static_assert(std::is_same_v); assert(base(it.base()) == &ts[0]); assert(base(result.base()) == &ts[1]); } } } constexpr bool test() { using Ptr = std::tuple*; testOne>(); testOne>(); testOne>(); testOne>(); testOne>(); testOne(); return true; } int main(int, char**) { test(); static_assert(test()); return 0; }