138 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 begin() requires (!simple-view<V>);12// constexpr auto begin() const requires range<const V>;13 14#include <cassert>15#include <ranges>16#include <utility>17 18#include "test_macros.h"19#include "test_iterators.h"20#include "test_range.h"21#include "types.h"22 23struct NonCommonSimpleView : std::ranges::view_base {24 int* begin() const;25 sentinel_wrapper<int*> end() const;26 std::size_t size() { return 0; } // deliberately non-const27};28static_assert(std::ranges::sized_range<NonCommonSimpleView>);29static_assert(!std::ranges::sized_range<const NonCommonSimpleView>);30 31using CommonInputIterPtrConstInt = common_input_iterator<const int*>;32using CountedCommonInputIterPtrConstInt = std::counted_iterator<CommonInputIterPtrConstInt>;33 34constexpr bool test() {35 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};36 37 // simple-view<V> && sized_range<V> && random_access_range<V>38 {39 using ViewTested = SizedRandomAccessView;40 static_assert(simple_view<ViewTested>);41 static_assert(std::ranges::sized_range<ViewTested>);42 static_assert(std::ranges::random_access_range<ViewTested>);43 44 std::ranges::take_view<ViewTested> tv(ViewTested(buffer), 4);45 assert(tv.begin() == ViewTested(buffer).begin());46 ASSERT_SAME_TYPE(decltype(tv.begin()), RandomAccessIter);47 48 const std::ranges::take_view<ViewTested> ctv(ViewTested(buffer), 4);49 assert(ctv.begin() == ViewTested(buffer).begin());50 ASSERT_SAME_TYPE(decltype(ctv.begin()), RandomAccessIter);51 }52 53 // simple-view<V> && sized_range<V> && !random_access_range<V>54 {55 using ViewTested = SizedForwardView;56 static_assert(simple_view<ViewTested>);57 static_assert(std::ranges::sized_range<ViewTested>);58 static_assert(!std::ranges::random_access_range<ViewTested>);59 60 std::ranges::take_view<ViewTested> tv(ViewTested{buffer}, 16); // underlying size is 861 assert(tv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 8)); // expect min(8, 16)62 ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<ForwardIter>);63 64 const std::ranges::take_view<ViewTested> ctv(ViewTested{buffer}, 4);65 assert(ctv.begin() == std::counted_iterator<ForwardIter>(ForwardIter(buffer), 4));66 ASSERT_SAME_TYPE(decltype(ctv.begin()), std::counted_iterator<ForwardIter>);67 }68 69 // simple-view<V> && !sized_range<V>70 {71 using ViewTested = MoveOnlyView;72 static_assert(simple_view<ViewTested>);73 std::ranges::take_view<ViewTested> tv(ViewTested{buffer}, 4);74 assert(tv.begin() == std::counted_iterator<int*>(buffer, 4));75 ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);76 77 const std::ranges::take_view<ViewTested> ctv(ViewTested{buffer}, 4);78 assert(ctv.begin() == std::counted_iterator<int*>(buffer, 4));79 ASSERT_SAME_TYPE(decltype(ctv.begin()), std::counted_iterator<int*>);80 }81 82 // simple-view<V> && sized_range<V> && !sized_range<const V>83 {84 using ViewTested = NonCommonSimpleView;85 static_assert(simple_view<ViewTested>);86 static_assert(std::ranges::sized_range<ViewTested>);87 static_assert(!std::ranges::sized_range<const ViewTested>);88 89 std::ranges::take_view<ViewTested> tv{};90 ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator<int*>);91 ASSERT_SAME_TYPE(decltype(std::as_const(tv).begin()), std::counted_iterator<int*>);92 }93 94 // !simple-view<V> && !sized_range<V>95 {96 using ViewTested = NonSimpleNonSizedView;97 static_assert(!simple_view<ViewTested>);98 static_assert(!std::ranges::sized_range<ViewTested>);99 100 std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};101 // The count for the counted iterator is the count of the take_view (i.e., 4)102 assert(tv.begin() == CountedCommonInputIterPtrConstInt(CommonInputIterPtrConstInt(buffer), 4));103 ASSERT_SAME_TYPE(decltype(tv.begin()), CountedCommonInputIterPtrConstInt);104 }105 106 // !simple-view<V> && sized_range<V>107 {108 using ViewTested = NonSimpleSizedView;109 static_assert(!simple_view<ViewTested>);110 static_assert(std::ranges::sized_range<ViewTested>);111 112 std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};113 // The count for the counted iterator is the min(2, 4) (i.e., 2).114 assert(tv.begin() == CountedCommonInputIterPtrConstInt(CommonInputIterPtrConstInt(buffer), 2));115 ASSERT_SAME_TYPE(decltype(tv.begin()), CountedCommonInputIterPtrConstInt);116 }117 118 // !simple-view<V> && sized_range<V> && random_access_range<V>119 {120 using ViewTested = NonSimpleSizedRandomView;121 static_assert(!simple_view<ViewTested>);122 static_assert(std::ranges::sized_range<ViewTested>);123 static_assert(std::ranges::random_access_range<ViewTested>);124 125 std::ranges::take_view<ViewTested> tv{ViewTested{buffer, buffer + 2}, 4};126 assert(tv.begin() == random_access_iterator<const int*>(buffer));127 ASSERT_SAME_TYPE(decltype(tv.begin()), random_access_iterator<const int*>);128 }129 return true;130}131 132int main(int, char**) {133 test();134 static_assert(test());135 136 return 0;137}138