[libcxx-commits] [libcxx] 4ac87e3 - [libcxx][ranges] Add `unreachable_sentinel`.

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Aug 12 10:11:45 PDT 2021


Author: zoecarver
Date: 2021-08-12T10:11:27-07:00
New Revision: 4ac87e33785eaaed8a41d4880075ff346fab8a0d

URL: https://github.com/llvm/llvm-project/commit/4ac87e33785eaaed8a41d4880075ff346fab8a0d
DIFF: https://github.com/llvm/llvm-project/commit/4ac87e33785eaaed8a41d4880075ff346fab8a0d.diff

LOG: [libcxx][ranges] Add `unreachable_sentinel`.

Differential Revision: https://reviews.llvm.org/D107920

Added: 
    libcxx/include/__iterator/unreachable_sentinel.h
    libcxx/test/libcxx/diagnostics/detail.headers/iterator/unreachable_sentinel.module.verify.cpp
    libcxx/test/std/iterators/predef.iterators/unreachable.sentinel/unreachable_sentinel.pass.cpp

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/iterator
    libcxx/include/module.modulemap

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 62da52b74d905..d2760ee45ad3c 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -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

diff  --git a/libcxx/include/__iterator/unreachable_sentinel.h b/libcxx/include/__iterator/unreachable_sentinel.h
new file mode 100644
index 0000000000000..cbbccd7bb2887
--- /dev/null
+++ b/libcxx/include/__iterator/unreachable_sentinel.h
@@ -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

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index e0b25200bd9de..1f34d250f5a4d 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -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 = ptr
diff _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>

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index c50a140152749..f7c899c5fe535 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -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" }
     }
   }

diff  --git a/libcxx/test/libcxx/diagnostics/detail.headers/iterator/unreachable_sentinel.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/unreachable_sentinel.module.verify.cpp
new file mode 100644
index 0000000000000..d71b9e336bb5a
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/unreachable_sentinel.module.verify.cpp
@@ -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>

diff  --git a/libcxx/test/std/iterators/predef.iterators/unreachable.sentinel/unreachable_sentinel.pass.cpp b/libcxx/test/std/iterators/predef.iterators/unreachable.sentinel/unreachable_sentinel.pass.cpp
new file mode 100644
index 0000000000000..d3f7a612b6143
--- /dev/null
+++ b/libcxx/test/std/iterators/predef.iterators/unreachable.sentinel/unreachable_sentinel.pass.cpp
@@ -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;
+}


        


More information about the libcxx-commits mailing list