brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 2dddd84 Raw
133 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 12// constexpr iterator_t<R> begin();13// constexpr sentinel_t<R> end();14// constexpr auto begin() const requires range<const R>;15// constexpr auto end() const requires range<const R>;16 17#include <ranges>18 19#include <array>20#include <cassert>21#include <concepts>22#include <memory>23 24#include "test_iterators.h"25#include "test_macros.h"26 27struct Base {28  constexpr int *begin() { return nullptr; }29  constexpr auto end() { return sentinel_wrapper<int*>(nullptr); }30  constexpr char *begin() const { return nullptr; }31  constexpr auto end() const { return sentinel_wrapper<char*>(nullptr); }32};33static_assert(std::same_as<std::ranges::iterator_t<Base>, int*>);34static_assert(std::same_as<std::ranges::sentinel_t<Base>, sentinel_wrapper<int*>>);35static_assert(std::same_as<std::ranges::iterator_t<const Base>, char*>);36static_assert(std::same_as<std::ranges::sentinel_t<const Base>, sentinel_wrapper<char*>>);37 38struct NoConst {39  int* begin();40  sentinel_wrapper<int*> end();41};42 43struct DecayChecker {44  int*& begin() const;45  int*& end() const;46};47 48template <class T>49concept HasBegin = requires (T t) {50  t.begin();51};52 53template <class T>54concept HasEnd = requires (T t) {55  t.end();56};57 58constexpr bool test()59{60  {61    using OwningView = std::ranges::owning_view<Base>;62    OwningView ov;63    std::same_as<int*> decltype(auto) b1 = static_cast<OwningView&>(ov).begin();64    std::same_as<int*> decltype(auto) b2 = static_cast<OwningView&&>(ov).begin();65    std::same_as<char*> decltype(auto) b3 = static_cast<const OwningView&>(ov).begin();66    std::same_as<char*> decltype(auto) b4 = static_cast<const OwningView&&>(ov).begin();67 68    std::same_as<sentinel_wrapper<int*>> decltype(auto) e1 = static_cast<OwningView&>(ov).end();69    std::same_as<sentinel_wrapper<int*>> decltype(auto) e2 = static_cast<OwningView&&>(ov).end();70    std::same_as<sentinel_wrapper<char*>> decltype(auto) e3 = static_cast<const OwningView&>(ov).end();71    std::same_as<sentinel_wrapper<char*>> decltype(auto) e4 = static_cast<const OwningView&&>(ov).end();72 73    assert(b1 == e1);74    assert(b2 == e2);75    assert(b3 == e3);76    assert(b4 == e4);77  }78  {79    // NoConst has non-const begin() and end(); so does the owning_view.80    using OwningView = std::ranges::owning_view<NoConst>;81    static_assert(HasBegin<OwningView&>);82    static_assert(HasBegin<OwningView&&>);83    static_assert(!HasBegin<const OwningView&>);84    static_assert(!HasBegin<const OwningView&&>);85    static_assert(HasEnd<OwningView&>);86    static_assert(HasEnd<OwningView&&>);87    static_assert(!HasEnd<const OwningView&>);88    static_assert(!HasEnd<const OwningView&&>);89  }90  {91    // DecayChecker's begin() and end() return references; make sure the owning_view decays them.92    using OwningView = std::ranges::owning_view<DecayChecker>;93    OwningView ov;94    ASSERT_SAME_TYPE(decltype(ov.begin()), int*);95    ASSERT_SAME_TYPE(decltype(ov.end()), int*);96  }97  {98    // Test an empty view.99    int a[] = {1};100    auto ov = std::ranges::owning_view(std::ranges::subrange(a, a));101    assert(ov.begin() == a);102    assert(std::as_const(ov).begin() == a);103    assert(ov.end() == a);104    assert(std::as_const(ov).end() == a);105  }106  {107    // Test a non-empty view.108    int a[] = {1};109    auto ov = std::ranges::owning_view(std::ranges::subrange(a, a+1));110    assert(ov.begin() == a);111    assert(std::as_const(ov).begin() == a);112    assert(ov.end() == a+1);113    assert(std::as_const(ov).end() == a+1);114  }115  {116    // Test a non-view.117    std::array<int, 2> a = {1, 2};118    auto ov = std::ranges::owning_view(std::move(a));119    assert(std::to_address(ov.begin()) != std::to_address(a.begin())); // because it points into the copy120    assert(std::to_address(std::as_const(ov).begin()) != std::to_address(a.begin()));121    assert(std::to_address(ov.end()) != std::to_address(a.end()));122    assert(std::to_address(std::as_const(ov).end()) != std::to_address(a.end()));123  }124  return true;125}126 127int main(int, char**) {128  test();129  static_assert(test());130 131  return 0;132}133