[libcxx-commits] [libcxx] 9e35e61 - [libc++] [ranges] Simplify our idiom for testing niebloid-ness.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 6 11:21:11 PST 2022


Author: Arthur O'Dwyer
Date: 2022-01-06T14:20:44-05:00
New Revision: 9e35e61aa435708ffe9361f768e8b0568b94bb30

URL: https://github.com/llvm/llvm-project/commit/9e35e61aa435708ffe9361f768e8b0568b94bb30
DIFF: https://github.com/llvm/llvm-project/commit/9e35e61aa435708ffe9361f768e8b0568b94bb30.diff

LOG: [libc++] [ranges] Simplify our idiom for testing niebloid-ness.

In the test files, replace the old-style tests with a simple static_assert,
matching the current style as depicted in e.g.
`ranges_uninitialized_default_construct.pass.cpp`.

Preserve `is_function_like` (but renamed to `is_niebloid`) at
ldionne's request. The removal of this test helper will happen
in D116570 if at all.

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

Added: 
    libcxx/test/support/is_niebloid.h

Modified: 
    libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp

Removed: 
    libcxx/test/support/test_standard_function.h


################################################################################
diff  --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp
index cc73e750144ca..8ce5a8e9a643d 100644
--- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp
@@ -13,82 +13,11 @@
 
 #include <iterator>
 
-#include "test_standard_function.h"
-
-static_assert(is_function_like<decltype(std::ranges::advance)>());
-
-// FIXME: We're bending the rules here by adding a new type to namespace std::ranges. Since this is
-// the standard library's test suite, this should be fine (we *are* the implementation), but it's
-// necessary at the time of writing since there aren't any iterators in std::ranges that we can
-// borrow for this test.
-namespace std::ranges {
-class fake_forward_iterator {
-public:
-  using value_type = int;
-  using 
diff erence_type = std::ptr
diff _t;
-  using iterator_category = std::forward_iterator_tag;
-
-  fake_forward_iterator() = default;
-
-  value_type operator*() const;
-  fake_forward_iterator& operator++();
-  fake_forward_iterator operator++(int);
-
-  bool operator==(fake_forward_iterator const&) const = default;
-};
-} // namespace std::ranges
-
-template <class I, class... Args>
-constexpr bool unqualified_lookup_works = requires(I i, Args... args) {
-  advance(i, args...);
-};
-
-static_assert(!unqualified_lookup_works<std::ranges::fake_forward_iterator, std::ptr
diff _t>);
-static_assert(!unqualified_lookup_works<std::ranges::fake_forward_iterator, std::ranges::fake_forward_iterator>);
-static_assert(
-    !unqualified_lookup_works<std::ranges::fake_forward_iterator, std::ptr
diff _t, std::ranges::fake_forward_iterator>);
-
-namespace test {
-template <class>
-class forward_iterator {
-public:
-  using value_type = int;
-  using 
diff erence_type = std::ptr
diff _t;
-  using iterator_category = std::forward_iterator_tag;
-
-  forward_iterator() = default;
-
-  value_type operator*() const;
-  forward_iterator& operator++();
-  forward_iterator operator++(int);
-
-  bool operator==(forward_iterator const&) const = default;
-};
-
-template <class I>
-void advance(forward_iterator<I>&, std::ptr
diff _t) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void advance(forward_iterator<I>&, forward_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void advance(forward_iterator<I>&, std::ptr
diff _t, forward_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-} // namespace test
-
-// TODO(varconst): simply check that `advance` is a variable and not a function.
-// When found by unqualified ([basic.lookup.unqual]) name lookup for the postfix-expression in a
-// function call ([expr.call]), they inhibit argument-dependent name lookup.
-void adl_inhibition() {
-  test::forward_iterator<int*> x;
-
-  using std::ranges::advance;
-  advance(x, 0);
-  advance(x, x);
-  advance(x, 0, x);
-}
+#include "is_niebloid.h"
+#include "test_macros.h"
+
+// Because this is a variable and not a function, it's guaranteed that ADL won't be used. However,
+// implementations are allowed to use a 
diff erent mechanism to achieve this effect, so this check is
+// libc++-specific.
+LIBCPP_STATIC_ASSERT(std::is_class_v<decltype(std::ranges::advance)>);
+LIBCPP_STATIC_ASSERT(is_niebloid<decltype(std::ranges::advance)>());

diff  --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp
index c5bb8a9ddefa0..6f5e4b3783f3d 100644
--- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp
@@ -13,91 +13,11 @@
 
 #include <iterator>
 
-#include "test_standard_function.h"
-
-static_assert(is_function_like<decltype(std::ranges::next)>());
-
-// FIXME: We're bending the rules here by adding a new type to namespace std::ranges. Since this is
-// the standard library's test suite, this should be fine (we *are* the implementation), but it's
-// necessary at the time of writing since there aren't any iterators in std::ranges that we can
-// borrow for this test.
-namespace std::ranges {
-class fake_forward_iterator {
-public:
-  using value_type = int;
-  using 
diff erence_type = std::ptr
diff _t;
-  using iterator_category = std::forward_iterator_tag;
-
-  fake_forward_iterator() = default;
-
-  value_type operator*() const;
-  fake_forward_iterator& operator++();
-  fake_forward_iterator operator++(int);
-
-  bool operator==(fake_forward_iterator const&) const = default;
-};
-} // namespace std::ranges
-
-// The function templates defined in [range.iter.ops] are not found by argument-dependent name lookup ([basic.lookup.argdep]).
-template <class I, class... Args>
-constexpr bool unqualified_lookup_works = requires(I i, Args... args) {
-  next(i, args...);
-};
-
-static_assert(!unqualified_lookup_works<std::ranges::fake_forward_iterator>);
-static_assert(!unqualified_lookup_works<std::ranges::fake_forward_iterator, std::ptr
diff _t>);
-static_assert(!unqualified_lookup_works<std::ranges::fake_forward_iterator, std::ranges::fake_forward_iterator>);
-static_assert(
-    !unqualified_lookup_works<std::ranges::fake_forward_iterator, std::ptr
diff _t, std::ranges::fake_forward_iterator>);
-
-namespace test {
-template <class>
-class forward_iterator {
-public:
-  using value_type = int;
-  using 
diff erence_type = std::ptr
diff _t;
-  using iterator_category = std::forward_iterator_tag;
-
-  forward_iterator() = default;
-
-  value_type operator*() const;
-  forward_iterator& operator++();
-  forward_iterator operator++(int);
-
-  bool operator==(forward_iterator const&) const = default;
-};
-
-template <class I>
-void next(forward_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void next(forward_iterator<I>, std::ptr
diff _t) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void next(forward_iterator<I>, forward_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void next(forward_iterator<I>, std::ptr
diff _t, forward_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-} // namespace test
-
-// TODO(varconst): simply check that `next` is a variable and not a function.
-// When found by unqualified ([basic.lookup.unqual]) name lookup for the postfix-expression in a
-// function call ([expr.call]), they inhibit argument-dependent name lookup.
-void adl_inhibition() {
-  test::forward_iterator<int*> x;
-
-  using std::ranges::next;
-
-  (void)next(x);
-  (void)next(x, 5);
-  (void)next(x, x);
-  (void)next(x, 6, x);
-}
+#include "is_niebloid.h"
+#include "test_macros.h"
+
+// Because this is a variable and not a function, it's guaranteed that ADL won't be used. However,
+// implementations are allowed to use a 
diff erent mechanism to achieve this effect, so this check is
+// libc++-specific.
+LIBCPP_STATIC_ASSERT(std::is_class_v<decltype(std::ranges::next)>);
+LIBCPP_STATIC_ASSERT(is_niebloid<decltype(std::ranges::next)>());

diff  --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp
index 0f72a8e841e86..a87464feb25f5 100644
--- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp
@@ -13,85 +13,11 @@
 
 #include <iterator>
 
-#include "test_iterators.h"
-#include "test_standard_function.h"
-
-static_assert(is_function_like<decltype(std::ranges::prev)>());
-
-namespace std::ranges {
-class fake_bidirectional_iterator {
-public:
-  using value_type = int;
-  using 
diff erence_type = std::ptr
diff _t;
-  using iterator_category = std::bidirectional_iterator_tag;
-
-  fake_bidirectional_iterator() = default;
-
-  value_type operator*() const;
-  fake_bidirectional_iterator& operator++();
-  fake_bidirectional_iterator operator++(int);
-  fake_bidirectional_iterator& operator--();
-  fake_bidirectional_iterator operator--(int);
-
-  bool operator==(fake_bidirectional_iterator const&) const = default;
-};
-} // namespace std::ranges
-
-// The function templates defined in [range.iter.ops] are not found by argument-dependent name lookup ([basic.lookup.argdep]).
-template <class I, class... Args>
-constexpr bool unqualified_lookup_works = requires(I i, Args... args) {
-  prev(i, args...);
-};
-
-static_assert(!unqualified_lookup_works<std::ranges::fake_bidirectional_iterator>);
-static_assert(!unqualified_lookup_works<std::ranges::fake_bidirectional_iterator, std::ptr
diff _t>);
-static_assert(!unqualified_lookup_works<std::ranges::fake_bidirectional_iterator, std::ptr
diff _t,
-                                        std::ranges::fake_bidirectional_iterator>);
-
-namespace test {
-template <class>
-class bidirectional_iterator {
-public:
-  using value_type = int;
-  using 
diff erence_type = std::ptr
diff _t;
-  using iterator_category = std::bidirectional_iterator_tag;
-
-  bidirectional_iterator() = default;
-
-  value_type operator*() const;
-  bidirectional_iterator& operator++();
-  bidirectional_iterator operator++(int);
-  bidirectional_iterator& operator--();
-  bidirectional_iterator operator--(int);
-
-  bool operator==(bidirectional_iterator const&) const = default;
-};
-
-template <class I>
-void prev(bidirectional_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void prev(bidirectional_iterator<I>, std::ptr
diff _t) {
-  static_assert(std::same_as<I, I*>);
-}
-
-template <class I>
-void prev(bidirectional_iterator<I>, std::ptr
diff _t, bidirectional_iterator<I>) {
-  static_assert(std::same_as<I, I*>);
-}
-} // namespace test
-
-// TODO(varconst): simply check that `prev` is a variable and not a function.
-// When found by unqualified ([basic.lookup.unqual]) name lookup for the postfix-expression in a
-// function call ([expr.call]), they inhibit argument-dependent name lookup.
-void adl_inhibition() {
-  test::bidirectional_iterator<int*> x;
-
-  using std::ranges::prev;
-
-  (void)prev(x);
-  (void)prev(x, 5);
-  (void)prev(x, 6, x);
-}
+#include "is_niebloid.h"
+#include "test_macros.h"
+
+// Because this is a variable and not a function, it's guaranteed that ADL won't be used. However,
+// implementations are allowed to use a 
diff erent mechanism to achieve this effect, so this check is
+// libc++-specific.
+LIBCPP_STATIC_ASSERT(std::is_class_v<decltype(std::ranges::prev)>);
+LIBCPP_STATIC_ASSERT(is_niebloid<decltype(std::ranges::prev)>());

diff  --git a/libcxx/test/support/test_standard_function.h b/libcxx/test/support/is_niebloid.h
similarity index 84%
rename from libcxx/test/support/test_standard_function.h
rename to libcxx/test/support/is_niebloid.h
index 1e207cfdac00b..2405d498939d2 100644
--- a/libcxx/test/support/test_standard_function.h
+++ b/libcxx/test/support/is_niebloid.h
@@ -5,8 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#ifndef LIBCXX_TEST_SUPPORT_TEST_STANDARD_FUNCTION_H
-#define LIBCXX_TEST_SUPPORT_TEST_STANDARD_FUNCTION_H
+#ifndef LIBCXX_TEST_SUPPORT_IS_NIEBLOID_H
+#define LIBCXX_TEST_SUPPORT_IS_NIEBLOID_H
 
 #include "test_macros.h"
 
@@ -17,7 +17,7 @@ constexpr bool is_addressable = requires(T t) {
 };
 
 template <class T>
-constexpr bool is_function_like() {
+constexpr bool is_niebloid() {
   using X = std::remove_cvref_t<T>;
   static_assert(!is_addressable<X>);
   static_assert(!is_addressable<X const>);
@@ -36,4 +36,4 @@ constexpr bool is_function_like() {
 }
 #endif
 
-#endif // LIBCXX_TEST_SUPPORT_TEST_STANDARD_FUNCTION_H
+#endif // LIBCXX_TEST_SUPPORT_IS_NIEBLOID_H


        


More information about the libcxx-commits mailing list