brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 56ac55c Raw
104 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 V base() const & requires copy_constructible<V> { return base_; }12// constexpr V base() && { return std::move(base_); }13 14#include <cassert>15#include <ranges>16#include <type_traits>17#include <utility>18 19#include "MoveOnly.h"20 21struct View : std::ranges::view_base {22  int i;23  int* begin() const;24  int* end() const;25};26 27struct MoveOnlyView : View {28  MoveOnly mo;29};30 31template <class T>32concept HasBase = requires(T&& t) { std::forward<T>(t).base(); };33 34static_assert(HasBase<std::ranges::split_view<View, View> const&>);35static_assert(HasBase<std::ranges::split_view<View, View>&&>);36 37static_assert(!HasBase<std::ranges::split_view<MoveOnlyView, View> const&>);38static_assert(HasBase<std::ranges::split_view<MoveOnlyView, View>&&>);39 40constexpr bool test() {41  // const &42  {43    const std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};44    std::same_as<View> decltype(auto) v = sv.base();45    assert(v.i == 5);46  }47 48  // &49  {50    std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};51    std::same_as<View> decltype(auto) v = sv.base();52    assert(v.i == 5);53  }54 55  // &&56  {57    std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};58    std::same_as<View> decltype(auto) v = std::move(sv).base();59    assert(v.i == 5);60  }61 62  // const &&63  {64    std::ranges::split_view<View, View> sv{View{{}, 5}, View{{}, 0}};65    std::same_as<View> decltype(auto) v = std::move(sv).base();66    assert(v.i == 5);67  }68 69  // move only70  {71    std::ranges::split_view<MoveOnlyView, View> sv{MoveOnlyView{{}, 5}, View{{}, 0}};72    std::same_as<MoveOnlyView> decltype(auto) v = std::move(sv).base();73    assert(v.mo.get() == 5);74  }75 76  // LWG 3590 split_view::base() const & is overconstrained77  {78    struct CopyCtorButNotAssignable : std::ranges::view_base {79      int i;80      constexpr CopyCtorButNotAssignable(int ii) : i(ii) {}81      constexpr CopyCtorButNotAssignable(const CopyCtorButNotAssignable&)            = default;82      constexpr CopyCtorButNotAssignable(CopyCtorButNotAssignable&&)                 = default;83      constexpr CopyCtorButNotAssignable& operator=(CopyCtorButNotAssignable&&)      = default;84      constexpr CopyCtorButNotAssignable& operator=(const CopyCtorButNotAssignable&) = delete;85      constexpr int* begin() const { return nullptr; }86      constexpr int* end() const { return nullptr; }87    };88    static_assert(std::copy_constructible<CopyCtorButNotAssignable>);89    static_assert(!std::copyable<CopyCtorButNotAssignable>);90    const std::ranges::split_view<CopyCtorButNotAssignable, CopyCtorButNotAssignable> sv{91        CopyCtorButNotAssignable{5}, CopyCtorButNotAssignable{5}};92    std::same_as<CopyCtorButNotAssignable> decltype(auto) v = sv.base();93    assert(v.i == 5);94  }95 96  return true;97}98 99int main(int, char**) {100  test();101  static_assert(test());102  return 0;103}104