brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · cc3fcfd Raw
100 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++17, c++2010 11// <ranges>12 13// constexpr View base() const& requires copy_constructible<View>;14// constexpr View base() &&;15 16#include <ranges>17 18#include <cassert>19#include <concepts>20#include <utility>21 22struct Range : std::ranges::view_base {23  constexpr explicit Range(int* b, int* e) : begin_(b), end_(e) {}24  constexpr Range(Range const& other) : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {}25  constexpr Range(Range&& other) : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {}26  Range& operator=(Range const&) = default;27  Range& operator=(Range&&)      = default;28  constexpr int* begin() const { return begin_; }29  constexpr int* end() const { return end_; }30 31  int* begin_;32  int* end_;33  bool wasCopyInitialized = false;34  bool wasMoveInitialized = false;35};36 37static_assert(std::ranges::view<Range>);38static_assert(std::ranges::forward_range<Range>);39 40struct Pred {41  bool operator()(int, int) const;42};43 44struct NonCopyableRange : std::ranges::view_base {45  explicit NonCopyableRange(int*, int*);46  NonCopyableRange(NonCopyableRange const&)            = delete;47  NonCopyableRange(NonCopyableRange&&)                 = default;48  NonCopyableRange& operator=(NonCopyableRange const&) = default;49  NonCopyableRange& operator=(NonCopyableRange&&)      = default;50  int* begin() const;51  int* end() const;52};53 54static_assert(!std::copy_constructible<NonCopyableRange>);55 56template <typename T>57concept CanCallBaseOn = requires(T t) { std::forward<T>(t).base(); };58 59constexpr bool test() {60  int buff[] = {1, 2, 3, 4};61 62  // Check the const& overload63  {64    Range range(buff, buff + 4);65    std::ranges::chunk_by_view<Range, Pred> const view(range, Pred{});66    std::same_as<Range> decltype(auto) result = view.base();67    assert(result.wasCopyInitialized);68    assert(result.begin() == buff);69    assert(result.end() == buff + 4);70  }71 72  // Check the && overload73  {74    Range range(buff, buff + 4);75    std::ranges::chunk_by_view<Range, Pred> view(range, Pred{});76    std::same_as<Range> decltype(auto) result = std::move(view).base();77    assert(result.wasMoveInitialized);78    assert(result.begin() == buff);79    assert(result.end() == buff + 4);80  }81 82  // Ensure the const& overload is not considered when the base is not copy-constructible83  {84    static_assert(!CanCallBaseOn<std::ranges::chunk_by_view<NonCopyableRange, Pred> const&>);85    static_assert(!CanCallBaseOn<std::ranges::chunk_by_view<NonCopyableRange, Pred>&>);86    static_assert(!CanCallBaseOn<std::ranges::chunk_by_view<NonCopyableRange, Pred> const&&>);87    static_assert(CanCallBaseOn<std::ranges::chunk_by_view<NonCopyableRange, Pred>&&>);88    static_assert(CanCallBaseOn<std::ranges::chunk_by_view<NonCopyableRange, Pred>>);89  }90 91  return true;92}93 94int main(int, char**) {95  test();96  static_assert(test());97 98  return 0;99}100