[libcxx-commits] [libcxx] 89599e8 - [libcxx][ranges] Add concepts in range.utility.helpers.

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 4 09:56:41 PDT 2021


Author: zoecarver
Date: 2021-06-04T09:56:31-07:00
New Revision: 89599e8b201a85c4555e72580b7137e4cce71c94

URL: https://github.com/llvm/llvm-project/commit/89599e8b201a85c4555e72580b7137e4cce71c94
DIFF: https://github.com/llvm/llvm-project/commit/89599e8b201a85c4555e72580b7137e4cce71c94.diff

LOG: [libcxx][ranges] Add concepts in range.utility.helpers.

There are no changes to public APIs.

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

Added: 
    libcxx/test/libcxx/ranges/range.utility.helpers/different_from.compile.pass.cpp
    libcxx/test/libcxx/ranges/range.utility.helpers/has_arrow.compile.pass.cpp
    libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp

Modified: 
    libcxx/include/__iterator/concepts.h
    libcxx/include/__iterator/iterator_traits.h
    libcxx/include/__ranges/view.h
    libcxx/include/concepts

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index 654d27bf250bf..8b83eb1e90c0c 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -168,6 +168,10 @@ concept contiguous_iterator =
     { _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
   };
 
+
+template<class _Ip>
+concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); });
+
 // clang-format on
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)

diff  --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h
index 307ee143c1d2f..06b199b85979e 100644
--- a/libcxx/include/__iterator/iterator_traits.h
+++ b/libcxx/include/__iterator/iterator_traits.h
@@ -255,13 +255,7 @@ struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typ
 // Otherwise, if `decltype(declval<I&>().operator->())` is well-formed, then `pointer` names that
 // type.
 template<class _Ip>
-concept __has_arrow =
-  requires(_Ip& __i) {
-    __i.operator->();
-  };
-
-template<class _Ip>
-  requires __has_arrow<_Ip> && (!__has_member_pointer<_Ip>)
+  requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>)
 struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> {
   using type = decltype(declval<_Ip&>().operator->());
 };

diff  --git a/libcxx/include/__ranges/view.h b/libcxx/include/__ranges/view.h
index 11c0ae2db072d..55f8928f3c597 100644
--- a/libcxx/include/__ranges/view.h
+++ b/libcxx/include/__ranges/view.h
@@ -40,6 +40,11 @@ concept view =
   default_initializable<_Tp> &&
   enable_view<_Tp>;
 
+template<class _Range>
+concept __simple_view =
+  view<_Range> && range<const _Range> &&
+  same_as<iterator_t<_Range>, iterator_t<const _Range>> &&
+  same_as<sentinel_t<_Range>, iterator_t<const _Range>>;
 } // end namespace ranges
 
 #endif // !_LIBCPP_HAS_NO_RANGES

diff  --git a/libcxx/include/concepts b/libcxx/include/concepts
index 6c8f325af8afa..0b51f53dcc393 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -442,6 +442,9 @@ concept equivalence_relation = relation<_Rp, _Tp, _Up>;
 template<class _Rp, class _Tp, class _Up>
 concept strict_weak_order = relation<_Rp, _Tp, _Up>;
 
+template<class _Tp, class _Up>
+concept __
diff erent_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
+
 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS)
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/test/libcxx/ranges/range.utility.helpers/
diff erent_from.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.utility.helpers/
diff erent_from.compile.pass.cpp
new file mode 100644
index 0000000000000..ecea0eeb38908
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.utility.helpers/
diff erent_from.compile.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+
+#include <ranges>
+
+#include "test_macros.h"
+
+static_assert(std::__
diff erent_from<int, char>);
+static_assert(std::__
diff erent_from<const int, char>);
+static_assert(!std::__
diff erent_from<const int, int>);
+static_assert(!std::__
diff erent_from<const volatile int, int>);
+static_assert(!std::__
diff erent_from<const int&, int>);
+static_assert(!std::__
diff erent_from<int&, int>);
+static_assert(!std::__
diff erent_from<int&&, int>);
+static_assert(!std::__
diff erent_from<int, int&>);
+static_assert(!std::__
diff erent_from<int&, const int&>);
+static_assert(!std::__
diff erent_from<int(&)(), int()>);
+static_assert(std::__
diff erent_from<int(&)(), int(*)()>);
+

diff  --git a/libcxx/test/libcxx/ranges/range.utility.helpers/has_arrow.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.utility.helpers/has_arrow.compile.pass.cpp
new file mode 100644
index 0000000000000..889cf8b215e0d
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.utility.helpers/has_arrow.compile.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+
+#include <ranges>
+
+#include "test_macros.h"
+
+struct simple_iter {
+    typedef std::input_iterator_tag         iterator_category;
+    typedef int                             value_type;
+    typedef std::ptr
diff _t                  
diff erence_type;
+    typedef int*                            pointer;
+    typedef int&                            reference;
+
+    reference operator*() const;
+    pointer operator->() const;
+    friend bool operator==(const simple_iter&, const simple_iter&);
+    friend bool operator< (const simple_iter&, const simple_iter&);
+    friend bool operator<=(const simple_iter&, const simple_iter&);
+    friend bool operator> (const simple_iter&, const simple_iter&);
+    friend bool operator>=(const simple_iter&, const simple_iter&);
+
+    simple_iter& operator++();
+    simple_iter operator++(int);
+};
+
+struct no_star {
+    typedef std::input_iterator_tag         iterator_category;
+    typedef int                             value_type;
+    typedef std::ptr
diff _t                  
diff erence_type;
+    typedef int*                            pointer;
+    typedef int&                            reference;
+
+ /* reference operator*() const; */
+    pointer operator->() const;
+    friend bool operator==(const simple_iter&, const simple_iter&);
+    friend bool operator< (const simple_iter&, const simple_iter&);
+    friend bool operator<=(const simple_iter&, const simple_iter&);
+    friend bool operator> (const simple_iter&, const simple_iter&);
+    friend bool operator>=(const simple_iter&, const simple_iter&);
+
+    simple_iter& operator++();
+    simple_iter operator++(int);
+};
+
+struct no_arrow {
+    typedef std::input_iterator_tag         iterator_category;
+    typedef int                             value_type;
+    typedef std::ptr
diff _t                  
diff erence_type;
+    typedef int*                            pointer;
+    typedef int&                            reference;
+
+    reference operator*() const;
+ /* pointer operator->() const; */
+    friend bool operator==(const simple_iter&, const simple_iter&);
+    friend bool operator< (const simple_iter&, const simple_iter&);
+    friend bool operator<=(const simple_iter&, const simple_iter&);
+    friend bool operator> (const simple_iter&, const simple_iter&);
+    friend bool operator>=(const simple_iter&, const simple_iter&);
+
+    simple_iter& operator++();
+    simple_iter operator++(int);
+};
+
+struct E {};
+struct Incomplete;
+
+static_assert(std::__has_arrow<int*>);
+static_assert(std::__has_arrow<E*>);
+static_assert(!std::__has_arrow<Incomplete*>); // Because it's not an input_iterator.
+static_assert(std::__has_arrow<simple_iter>);
+static_assert(!std::__has_arrow<no_star>);
+static_assert(!std::__has_arrow<no_arrow>);

diff  --git a/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp
new file mode 100644
index 0000000000000..c544d922c1812
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <ranges>
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: gcc-10
+
+#include <ranges>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+struct SimpleView : std::ranges::view_base {
+  friend int* begin(SimpleView&);
+  friend int* begin(SimpleView const&);
+  friend int* end(SimpleView&);
+  friend int* end(SimpleView const&);
+};
+
+struct WrongConstView : std::ranges::view_base {
+  friend       int* begin(WrongConstView&);
+  friend const int* begin(WrongConstView const&);
+  friend       int* end(WrongConstView&);
+  friend const int* end(WrongConstView const&);
+};
+
+struct NoConstView : std::ranges::view_base {
+  friend int* begin(NoConstView&);
+  friend int* end(NoConstView&);
+};
+
+struct DifferentSentinel : std::ranges::view_base {
+  friend int* begin(DifferentSentinel&);
+  friend int* begin(DifferentSentinel const&);
+  friend sentinel_wrapper<int*> end(DifferentSentinel&);
+  friend sentinel_wrapper<int*> end(DifferentSentinel const&);
+};
+
+static_assert( std::ranges::__simple_view<SimpleView>);
+static_assert(!std::ranges::__simple_view<WrongConstView>);
+static_assert(!std::ranges::__simple_view<NoConstView>);
+static_assert(!std::ranges::__simple_view<DifferentSentinel>);


        


More information about the libcxx-commits mailing list