//===----------------------------------------------------------------------===// // // 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 // template // concept viewable_range; #include #include #include "test_iterators.h" #include "test_range.h" // The constraints we have in viewable_range are: // range // view> // constructible_from, T> // lvalue_reference_t || movable> // is-initializer-list // // We test all the relevant combinations of satisfying/not satisfying those constraints. // viewable_range is not satisfied for (range=false, view=*, constructible_from=*, lvalue-or-movable=*) struct T1 { }; static_assert(!std::ranges::range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); // viewable_range is satisfied for (range=true, view=true, constructible_from=true, lvalue-or-movable=true) struct T2 : test_range, std::ranges::view_base { T2(T2 const&) = default; }; static_assert(std::ranges::range); static_assert(std::ranges::view); static_assert(std::constructible_from); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); // viewable_range is satisfied for (range=true, view=true, constructible_from=true, lvalue-or-movable=false) struct T3 : test_range, std::ranges::view_base { T3(T3 const&) = default; }; static_assert(std::ranges::range); static_assert(std::ranges::view); static_assert(std::constructible_from); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); static_assert(std::ranges::viewable_range); // viewable_range is not satisfied for (range=true, view=true, constructible_from=false, lvalue-or-movable=true) struct T4 : test_range, std::ranges::view_base { T4(T4 const&) = delete; T4(T4&&) = default; // necessary to model view T4& operator=(T4&&) = default; // necessary to model view }; static_assert(std::ranges::range); static_assert(std::ranges::view>); static_assert(!std::constructible_from, T4 const&>); static_assert(!std::ranges::viewable_range); // A type that satisfies (range=true, view=true, constructible_from=false, lvalue-or-movable=false) can't be formed, // because views are movable by definition // viewable_range is satisfied for (range=true, view=false, constructible_from=true, lvalue-or-movable=true)... struct T5 : test_range { }; static_assert( std::ranges::range); static_assert(!std::ranges::view); static_assert( std::constructible_from); static_assert( std::movable); static_assert(!std::movable); static_assert( std::ranges::viewable_range); // movable static_assert( std::ranges::viewable_range); // movable static_assert( std::ranges::viewable_range); // movable static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); // lvalue static_assert(!std::ranges::viewable_range); // ...but not if the (non-view, lvalue-or-movable) range is an initializer_list. static_assert( std::ranges::range>); static_assert(!std::ranges::view>); static_assert( std::constructible_from, std::initializer_list>); static_assert( std::movable>); static_assert(!std::ranges::viewable_range>); static_assert( std::ranges::viewable_range&>); static_assert(!std::ranges::viewable_range&&>); static_assert(!std::ranges::viewable_range const>); static_assert( std::ranges::viewable_range const&>); static_assert(!std::ranges::viewable_range const&&>); // viewable_range is not satisfied for (range=true, view=false, constructible_from=true, lvalue-or-movable=false) struct T6 : test_range { T6(T6&&); T6& operator=(T6&&) = delete; }; static_assert( std::ranges::range); static_assert(!std::ranges::view); static_assert( std::constructible_from); static_assert(!std::movable); static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); // lvalue static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); // lvalue static_assert(!std::ranges::viewable_range); // viewable_range is satisfied for (range=true, view=false, constructible_from=false, lvalue-or-movable=true) struct T7 : test_range { T7(T7 const&) = delete; }; static_assert(std::ranges::range); static_assert(!std::ranges::view>); static_assert(!std::constructible_from, T7&>); static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); // viewable_range is not satisfied for (range=true, view=false, constructible_from=false, lvalue-or-movable=false) struct T8 : test_range { T8(T8 const&) = delete; }; static_assert(std::ranges::range); static_assert(!std::ranges::view); static_assert(!std::constructible_from); static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert( std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); // Test with a few degenerate types static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); // not a range static_assert( std::ranges::viewable_range); // OK, lvalue static_assert(!std::ranges::viewable_range); static_assert(!std::ranges::viewable_range); // Test ADL-proofing. struct Incomplete; template struct Holder { T t; }; static_assert(!std::ranges::viewable_range*>); static_assert(!std::ranges::viewable_range*&>); static_assert(!std::ranges::viewable_range*&&>); static_assert(!std::ranges::viewable_range* const>); static_assert(!std::ranges::viewable_range* const&>); static_assert(!std::ranges::viewable_range* const&&>); static_assert(!std::ranges::viewable_range*[10]>); static_assert( std::ranges::viewable_range*(&)[10]>); static_assert(!std::ranges::viewable_range*(&&)[10]>); static_assert(!std::ranges::viewable_range* const[10]>); static_assert( std::ranges::viewable_range* const(&)[10]>); static_assert(!std::ranges::viewable_range* const(&&)[10]>);