1d8fad661SChristopher Di Bella //===----------------------------------------------------------------------===// 2d8fad661SChristopher Di Bella // 3d8fad661SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4d8fad661SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 5d8fad661SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6d8fad661SChristopher Di Bella // 7d8fad661SChristopher Di Bella //===----------------------------------------------------------------------===// 8d8fad661SChristopher Di Bella 9d8fad661SChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17 10d8fad661SChristopher Di Bella 11f192616cSLouis Dionne // template<class R> 12d8fad661SChristopher Di Bella // concept common_range; 13d8fad661SChristopher Di Bella 14d8fad661SChristopher Di Bella #include <ranges> 15d8fad661SChristopher Di Bella 16d8fad661SChristopher Di Bella #include "test_iterators.h" 17d8fad661SChristopher Di Bella 184a47ac7dSLouis Dionne template<class It> struct Common { It begin() const; It end() const; }; 194a47ac7dSLouis Dionne template<class It> struct NonCommon { It begin() const; sentinel_wrapper<It> end() const; }; 204a47ac7dSLouis Dionne template<class It, class Sent> struct Range { It begin() const; Sent end() const; }; 21d8fad661SChristopher Di Bella 224a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<Common<cpp17_input_iterator<int*>>>); // not a sentinel for itself 234a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<Common<cpp20_input_iterator<int*>>>); // not a sentinel for itself 244a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Common<forward_iterator<int*>>>); 254a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Common<bidirectional_iterator<int*>>>); 264a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Common<random_access_iterator<int*>>>); 274a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Common<contiguous_iterator<int*>>>); 284a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Common<int*>>); 29d8fad661SChristopher Di Bella 304a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<cpp17_input_iterator<int*>>>); 314a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<cpp20_input_iterator<int*>>>); 324a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<forward_iterator<int*>>>); 334a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<bidirectional_iterator<int*>>>); 344a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<random_access_iterator<int*>>>); 354a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<contiguous_iterator<int*>>>); 364a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<int*>>); 37d8fad661SChristopher Di Bella 384a47ac7dSLouis Dionne // Test when begin() and end() only differ by their constness. 394a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<Range<int*, int const*>>); 40d8fad661SChristopher Di Bella 414a47ac7dSLouis Dionne // Simple test with a sized_sentinel. 424a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<Range<int*, sized_sentinel<int*>>>); 439d7c420aSLouis Dionne 444a47ac7dSLouis Dionne // Make sure cv-qualification doesn't impact the concept when begin() and end() have matching qualifiers. 454a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Common<forward_iterator<int*>> const>); 464a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<NonCommon<forward_iterator<int*>> const>); 47d8fad661SChristopher Di Bella 484a47ac7dSLouis Dionne // Test with a range that's a common_range only when const-qualified. 494a47ac7dSLouis Dionne struct Range1 { 50d8fad661SChristopher Di Bella int* begin(); 51d8fad661SChristopher Di Bella int const* begin() const; 52d8fad661SChristopher Di Bella int const* end() const; 53d8fad661SChristopher Di Bella }; 544a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<Range1>); 554a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Range1 const>); 564a47ac7dSLouis Dionne 574a47ac7dSLouis Dionne // Test with a range that's a common_range only when not const-qualified. 584a47ac7dSLouis Dionne struct Range2 { 594a47ac7dSLouis Dionne int* begin() const; 604a47ac7dSLouis Dionne int* end(); 614a47ac7dSLouis Dionne int const* end() const; 624a47ac7dSLouis Dionne }; 634a47ac7dSLouis Dionne static_assert( std::ranges::common_range<Range2>); 644a47ac7dSLouis Dionne static_assert(!std::ranges::common_range<Range2 const>); 65*bf150e8dSArthur O'Dwyer 66*bf150e8dSArthur O'Dwyer // Test ADL-proofing. 67*bf150e8dSArthur O'Dwyer struct Incomplete; 68*bf150e8dSArthur O'Dwyer template<class T> struct Holder { T t; }; 69*bf150e8dSArthur O'Dwyer 70*bf150e8dSArthur O'Dwyer static_assert(!std::ranges::common_range<Holder<Incomplete>*>); 71*bf150e8dSArthur O'Dwyer static_assert(!std::ranges::common_range<Holder<Incomplete>*&>); 72*bf150e8dSArthur O'Dwyer static_assert(!std::ranges::common_range<Holder<Incomplete>*&&>); 73*bf150e8dSArthur O'Dwyer static_assert(!std::ranges::common_range<Holder<Incomplete>* const>); 74*bf150e8dSArthur O'Dwyer static_assert(!std::ranges::common_range<Holder<Incomplete>* const&>); 75*bf150e8dSArthur O'Dwyer static_assert(!std::ranges::common_range<Holder<Incomplete>* const&&>); 76*bf150e8dSArthur O'Dwyer 77*bf150e8dSArthur O'Dwyer static_assert( std::ranges::common_range<Holder<Incomplete>*[10]>); 78*bf150e8dSArthur O'Dwyer static_assert( std::ranges::common_range<Holder<Incomplete>*(&)[10]>); 79*bf150e8dSArthur O'Dwyer static_assert( std::ranges::common_range<Holder<Incomplete>*(&&)[10]>); 80*bf150e8dSArthur O'Dwyer static_assert( std::ranges::common_range<Holder<Incomplete>* const[10]>); 81*bf150e8dSArthur O'Dwyer static_assert( std::ranges::common_range<Holder<Incomplete>* const(&)[10]>); 82*bf150e8dSArthur O'Dwyer static_assert( std::ranges::common_range<Holder<Incomplete>* const(&&)[10]>); 83