99 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 const iterator_t<Base>& base() const & noexcept;12// constexpr iterator_t<Base> base() &&;13 14#include <cassert>15#include <ranges>16#include <tuple>17#include <type_traits>18#include <utility>19 20#include "MoveOnly.h"21#include "../types.h"22 23// Test Noexcept24template <class T>25concept IsBaseNoexcept =26 requires {27 { std::declval<T>().base() } noexcept;28 };29 30using BaseView = std::ranges::subrange<std::tuple<int>*>;31using ElementsIter = std::ranges::iterator_t<std::ranges::elements_view<BaseView, 0>>;32 33static_assert(IsBaseNoexcept<const ElementsIter&>);34static_assert(IsBaseNoexcept<ElementsIter&>);35static_assert(IsBaseNoexcept<const ElementsIter&&>);36LIBCPP_STATIC_ASSERT(!IsBaseNoexcept<ElementsIter&&>);37 38constexpr bool test() {39 std::tuple<int> t{5};40 41 // const &42 {43 const ElementsIter it{&t};44 decltype(auto) base = it.base();45 static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);46 assert(base == &t);47 }48 49 // &50 {51 ElementsIter it{&t};52 decltype(auto) base = it.base();53 static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);54 assert(base == &t);55 }56 57 // &&58 {59 ElementsIter it{&t};60 decltype(auto) base = std::move(it).base();61 static_assert(std::is_same_v<decltype(base), std::tuple<int>*>);62 assert(base == &t);63 }64 65 // const &&66 {67 const ElementsIter it{&t};68 decltype(auto) base = std::move(it).base();69 static_assert(std::is_same_v<decltype(base), std::tuple<int>* const&>);70 assert(base == &t);71 }72 73 // move only74 {75 struct MoveOnlyIter : IterBase<MoveOnlyIter> {76 MoveOnly mo;77 };78 struct Sent {79 constexpr bool operator==(const MoveOnlyIter&) const { return true; }80 };81 82 using MoveOnlyElemIter =83 std::ranges::iterator_t<std::ranges::elements_view<std::ranges::subrange<MoveOnlyIter, Sent>, 0>>;84 85 MoveOnlyElemIter it{MoveOnlyIter{{}, MoveOnly{5}}};86 decltype(auto) base = std::move(it).base();87 static_assert(std::is_same_v<decltype(base), MoveOnlyIter>);88 assert(base.mo.get() == 5);89 }90 91 return true;92}93 94int main(int, char**) {95 test();96 static_assert(test());97 return 0;98}99