//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17 // constexpr sentinel(sentinel s); // requires Const && convertible_to, sentinel_t>; #include #include #include "../types.h" #include "test_range.h" template struct convertible_sentinel_wrapper { explicit convertible_sentinel_wrapper() = default; constexpr convertible_sentinel_wrapper(const T& it) : it_(it) {} template requires std::convertible_to constexpr convertible_sentinel_wrapper(const convertible_sentinel_wrapper& other) : it_(other.it_) {} constexpr friend bool operator==(convertible_sentinel_wrapper const& self, const T& other) { return self.it_ == other; } T it_; }; struct ConstConvertibleView : BufferView*> { using BufferView*>::BufferView; using sentinel = convertible_sentinel_wrapper*>; using const_sentinel = convertible_sentinel_wrapper*>; constexpr BufferView* begin() { return data_; } constexpr const BufferView* begin() const { return data_; } constexpr sentinel end() { return sentinel(data_ + size_); } constexpr const_sentinel end() const { return const_sentinel(data_ + size_); } }; static_assert(!std::ranges::common_range); static_assert(std::convertible_to, std::ranges::sentinel_t>); static_assert(!simple_view); constexpr bool test() { int buffer[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; { BufferView inners[] = {buffer[0], buffer[1], buffer[2]}; ConstConvertibleView outer(inners); std::ranges::join_view jv(outer); auto sent1 = jv.end(); std::ranges::sentinel_t sent2 = sent1; assert(std::as_const(jv).begin() != sent2); assert(std::ranges::next(std::as_const(jv).begin(), 12) == sent2); // We cannot create a non-const sentinel from a const sentinel. static_assert(!std::constructible_from); } { // cannot create a const sentinel from a non-const sentinel if the underlying // const sentinel cannot be created from the underlying non-const sentinel using Inner = BufferView; using ConstInconvertibleOuter = BufferView, sentinel_wrapper>, bidirectional_iterator, sentinel_wrapper>>; using JoinView = std::ranges::join_view; using sentinel_t = std::ranges::sentinel_t; using const_sentinel_t = std::ranges::sentinel_t; static_assert(!std::constructible_from); static_assert(!std::constructible_from); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }