89 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 sentinel(sentinel<!Const> s)12// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;13 14#include <cassert>15#include <ranges>16#include <tuple>17 18#include "../types.h"19 20struct Sent {21 int i;22 constexpr Sent() = default;23 constexpr Sent(int ii) : i(ii) {}24 friend constexpr bool operator==(std::tuple<int>*, const Sent&) { return true; }25};26 27struct ConstSent {28 int i;29 constexpr ConstSent() = default;30 constexpr ConstSent(int ii) : i(ii) {}31 constexpr ConstSent(const Sent& s) : i(s.i) {}32 friend constexpr bool operator==(std::tuple<int>*, const ConstSent&) { return true; }33};34 35struct Range : std::ranges::view_base {36 std::tuple<int>* begin() const;37 Sent end();38 ConstSent end() const;39};40 41struct NonConvertConstSent {42 int i;43 constexpr NonConvertConstSent() = default;44 constexpr NonConvertConstSent(int ii) : i(ii) {}45 friend constexpr bool operator==(std::tuple<int>*, const NonConvertConstSent&) { return true; }46};47 48struct NonConvertConstSentRange : std::ranges::view_base {49 std::tuple<int>* begin() const;50 Sent end();51 NonConvertConstSent end() const;52};53 54// Test Constraint55static_assert(std::is_constructible_v<std::ranges::sentinel_t<const std::ranges::elements_view<Range, 0>>,56 std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>>);57 58// !Const59static_assert(!std::is_constructible_v<std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>,60 std::ranges::sentinel_t<const std::ranges::elements_view<Range, 0>>>);61 62// !convertible_to<sentinel_t<V>, sentinel_t<Base>>63static_assert(!std::is_constructible_v<64 std::ranges::sentinel_t<const std::ranges::elements_view<NonConvertConstSentRange, 0>>,65 std::ranges::sentinel_t<std::ranges::elements_view<NonConvertConstSentRange, 0>>>);66 67constexpr bool test() {68 // base is init correctly69 {70 using R = std::ranges::elements_view<Range, 0>;71 using Sentinel = std::ranges::sentinel_t<R>;72 using ConstSentinel = std::ranges::sentinel_t<const R>;73 static_assert(!std::same_as<Sentinel, ConstSentinel>);74 75 Sentinel s1(Sent{5});76 ConstSentinel s2 = s1;77 assert(s2.base().i == 5);78 }79 80 return true;81}82 83int main(int, char**) {84 test();85 static_assert(test());86 87 return 0;88}89