Index: 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.advance/special_function.compile.pass.cpp +++ libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp @@ -13,82 +13,9 @@ #include -#include "test_standard_function.h" +#include "test_macros.h" -static_assert(is_function_like()); - -// 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 difference_type = std::ptrdiff_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 -constexpr bool unqualified_lookup_works = requires(I i, Args... args) { - advance(i, args...); -}; - -static_assert(!unqualified_lookup_works); -static_assert(!unqualified_lookup_works); -static_assert( - !unqualified_lookup_works); - -namespace test { -template -class forward_iterator { -public: - using value_type = int; - using difference_type = std::ptrdiff_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 -void advance(forward_iterator&, std::ptrdiff_t) { - static_assert(std::same_as); -} - -template -void advance(forward_iterator&, forward_iterator) { - static_assert(std::same_as); -} - -template -void advance(forward_iterator&, std::ptrdiff_t, forward_iterator) { - static_assert(std::same_as); -} -} // 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 x; - - using std::ranges::advance; - advance(x, 0); - advance(x, x); - advance(x, 0, x); -} +// 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 different mechanism to achieve this effect, so this check is +// libc++-specific. +LIBCPP_STATIC_ASSERT(std::is_class_v); Index: 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.next/special_function.compile.pass.cpp +++ libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp @@ -13,91 +13,9 @@ #include -#include "test_standard_function.h" +#include "test_macros.h" -static_assert(is_function_like()); - -// 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 difference_type = std::ptrdiff_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 -constexpr bool unqualified_lookup_works = requires(I i, Args... args) { - next(i, args...); -}; - -static_assert(!unqualified_lookup_works); -static_assert(!unqualified_lookup_works); -static_assert(!unqualified_lookup_works); -static_assert( - !unqualified_lookup_works); - -namespace test { -template -class forward_iterator { -public: - using value_type = int; - using difference_type = std::ptrdiff_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 -void next(forward_iterator) { - static_assert(std::same_as); -} - -template -void next(forward_iterator, std::ptrdiff_t) { - static_assert(std::same_as); -} - -template -void next(forward_iterator, forward_iterator) { - static_assert(std::same_as); -} - -template -void next(forward_iterator, std::ptrdiff_t, forward_iterator) { - static_assert(std::same_as); -} -} // 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 x; - - using std::ranges::next; - - (void)next(x); - (void)next(x, 5); - (void)next(x, x); - (void)next(x, 6, x); -} +// 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 different mechanism to achieve this effect, so this check is +// libc++-specific. +LIBCPP_STATIC_ASSERT(std::is_class_v); Index: libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp =================================================================== --- libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp +++ libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp @@ -13,85 +13,9 @@ #include -#include "test_iterators.h" -#include "test_standard_function.h" +#include "test_macros.h" -static_assert(is_function_like()); - -namespace std::ranges { -class fake_bidirectional_iterator { -public: - using value_type = int; - using difference_type = std::ptrdiff_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 -constexpr bool unqualified_lookup_works = requires(I i, Args... args) { - prev(i, args...); -}; - -static_assert(!unqualified_lookup_works); -static_assert(!unqualified_lookup_works); -static_assert(!unqualified_lookup_works); - -namespace test { -template -class bidirectional_iterator { -public: - using value_type = int; - using difference_type = std::ptrdiff_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 -void prev(bidirectional_iterator) { - static_assert(std::same_as); -} - -template -void prev(bidirectional_iterator, std::ptrdiff_t) { - static_assert(std::same_as); -} - -template -void prev(bidirectional_iterator, std::ptrdiff_t, bidirectional_iterator) { - static_assert(std::same_as); -} -} // 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 x; - - using std::ranges::prev; - - (void)prev(x); - (void)prev(x, 5); - (void)prev(x, 6, x); -} +// 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 different mechanism to achieve this effect, so this check is +// libc++-specific. +LIBCPP_STATIC_ASSERT(std::is_class_v); Index: libcxx/test/support/test_standard_function.h =================================================================== --- libcxx/test/support/test_standard_function.h +++ /dev/null @@ -1,39 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 LIBCXX_TEST_SUPPORT_TEST_STANDARD_FUNCTION_H -#define LIBCXX_TEST_SUPPORT_TEST_STANDARD_FUNCTION_H - -#include "test_macros.h" - -#if TEST_STD_VER >= 20 -template -constexpr bool is_addressable = requires(T t) { - &t; -}; - -template -constexpr bool is_function_like() { - using X = std::remove_cvref_t; - static_assert(!is_addressable); - static_assert(!is_addressable); - - static_assert(std::destructible && !std::default_initializable); - - static_assert(!std::move_constructible); - static_assert(!std::assignable_from); - - static_assert(!std::copy_constructible); - static_assert(!std::assignable_from); - static_assert(!std::assignable_from); - static_assert(!std::assignable_from); - static_assert(std::is_final_v); - return true; -} -#endif - -#endif // LIBCXX_TEST_SUPPORT_TEST_STANDARD_FUNCTION_H