[libcxx][ranges] Add `unreachable_sentinel`.

Differential Revision: https://reviews.llvm.org/D107920
This commit is contained in:
zoecarver 2021-08-11 11:16:27 -07:00
parent 79fbddbea0
commit 4ac87e3378
6 changed files with 130 additions and 0 deletions

View File

@ -186,6 +186,7 @@ set(files
__iterator/reverse_access.h
__iterator/reverse_iterator.h
__iterator/size.h
__iterator/unreachable_sentinel.h
__iterator/wrap_iter.h
__libcpp_version
__locale

View File

@ -0,0 +1,38 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H
#define _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H
#include <__config>
#include <__iterator/concepts.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_RANGES)
struct unreachable_sentinel_t {
template<weakly_incrementable _Iter>
_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(unreachable_sentinel_t, const _Iter&) noexcept {
return false;
}
};
inline constexpr unreachable_sentinel_t unreachable_sentinel{};
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H

View File

@ -410,6 +410,10 @@ template<input_iterator I>
requires see below
struct iterator_traits<counted_iterator<I>>;
// [unreachable.sentinel], unreachable sentinel
struct unreachable_sentinel_t;
inline constexpr unreachable_sentinel_t unreachable_sentinel{};
template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
class istream_iterator
: public iterator<input_iterator_tag, T, Distance, const T*, const T&> // until C++17
@ -606,6 +610,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__iterator/reverse_access.h>
#include <__iterator/reverse_iterator.h>
#include <__iterator/size.h>
#include <__iterator/unreachable_sentinel.h>
#include <__iterator/wrap_iter.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>

View File

@ -548,6 +548,7 @@ module std [system] {
module reverse_access { private header "__iterator/reverse_access.h" }
module reverse_iterator { private header "__iterator/reverse_iterator.h" }
module size { private header "__iterator/size.h" }
module unreachable_sentinel { private header "__iterator/unreachable_sentinel.h" }
module wrap_iter { private header "__iterator/wrap_iter.h" }
}
}

View File

@ -0,0 +1,16 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: modules-build
// WARNING: This test was generated by 'generate_private_header_tests.py'
// and should not be edited manually.
// expected-error@*:* {{use of private header from outside its module: '__iterator/unreachable_sentinel.h'}}
#include <__iterator/unreachable_sentinel.h>

View File

@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// 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
// UNSUPPORTED: libcpp-no-concepts
// struct unreachable_sentinel_t;
// inline constexpr unreachable_sentinel_t unreachable_sentinel;
#include <iterator>
#include <cassert>
#include <concepts>
#include <type_traits>
#include "test_macros.h"
template<class T, class U>
concept weakly_equality_comparable_with = requires(const T& t, const U& u) {
{ t == u } -> std::same_as<bool>;
{ t != u } -> std::same_as<bool>;
{ u == t } -> std::same_as<bool>;
{ u != t } -> std::same_as<bool>;
};
constexpr bool test() {
static_assert(std::is_empty_v<std::unreachable_sentinel_t>);
static_assert(std::semiregular<std::unreachable_sentinel_t>);
static_assert(std::same_as<decltype(std::unreachable_sentinel), const std::unreachable_sentinel_t>);
auto sentinel = std::unreachable_sentinel;
int i = 42;
assert(i != sentinel);
assert(sentinel != i);
assert(!(i == sentinel));
assert(!(sentinel == i));
assert(&i != sentinel);
assert(sentinel != &i);
assert(!(&i == sentinel));
assert(!(sentinel == &i));
int *p = nullptr;
assert(p != sentinel);
assert(sentinel != p);
assert(!(p == sentinel));
assert(!(sentinel == p));
static_assert( weakly_equality_comparable_with<std::unreachable_sentinel_t, int>);
static_assert( weakly_equality_comparable_with<std::unreachable_sentinel_t, int*>);
static_assert(!weakly_equality_comparable_with<std::unreachable_sentinel_t, void*>);
ASSERT_NOEXCEPT(sentinel == p);
ASSERT_NOEXCEPT(sentinel != p);
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}