diff --git a/libcxx/include/__function_like.h b/libcxx/include/__function_like.h --- a/libcxx/include/__function_like.h +++ b/libcxx/include/__function_like.h @@ -16,14 +16,6 @@ #pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -_LIBCPP_BEGIN_NAMESPACE_STD - -#if !defined(_LIBCPP_HAS_NO_RANGES) - -namespace ranges { // Per [range.iter.ops.general] and [algorithms.requirements], functions in namespace std::ranges // can't be found by ADL and inhibit ADL when found by unqualified lookup. The easiest way to // facilitate this is to use function objects. @@ -32,25 +24,12 @@ // the properties that function objects get by default (e.g. semiregularity, addressability), to // limit the surface area of the unintended public interface, so as to curb the effect of Hyrum's // law. -struct __function_like { - __function_like() = delete; - __function_like(__function_like const&) = delete; - __function_like& operator=(__function_like const&) = delete; - - void operator&() const = delete; - - struct __tag { }; - -protected: - constexpr explicit __function_like(__tag) noexcept {} - ~__function_like() = default; -}; -} // namespace ranges - -#endif // !defined(_LIBCPP_HAS_NO_RANGES) - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS +#define _LIBCPP_FUNCTION_LIKE(x) \ + struct __tag {}; \ + _LIBCPP_HIDE_FROM_ABI constexpr explicit x(__tag) noexcept {} \ + x() = delete; \ + x(const x&) = delete; \ + void operator=(const x&) = delete; \ + void operator&() const = delete #endif // _LIBCPP___ITERATOR_FUNCTION_LIKE_H diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -16,11 +16,11 @@ #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> +#include <__utility/move.h> #include #include #include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -70,7 +70,8 @@ namespace ranges { // [range.iter.op.advance] -struct __advance_fn final : __function_like { +struct __advance_fn final { + _LIBCPP_FUNCTION_LIKE(__advance_fn); private: template _LIBCPP_HIDE_FROM_ABI @@ -97,8 +98,6 @@ } public: - constexpr explicit __advance_fn(__tag __x) noexcept : __function_like(__x) {} - // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template _LIBCPP_HIDE_FROM_ABI @@ -129,7 +128,7 @@ constexpr void operator()(_Ip& __i, _Sp __bound) const { // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound)`. if constexpr (assignable_from<_Ip&, _Sp>) { - __i = std::move(__bound); + __i = _VSTD::move(__bound); } // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound - i)`. else if constexpr (sized_sentinel_for<_Sp, _Ip>) { @@ -186,7 +185,7 @@ } }; -inline constexpr auto advance = __advance_fn(__function_like::__tag()); +inline constexpr auto advance = __advance_fn(__advance_fn::__tag()); } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__iterator/next.h b/libcxx/include/__iterator/next.h --- a/libcxx/include/__iterator/next.h +++ b/libcxx/include/__iterator/next.h @@ -42,9 +42,8 @@ #if !defined(_LIBCPP_HAS_NO_RANGES) namespace ranges { -struct __next_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __next_fn(__tag __x) noexcept : __function_like(__x) {} +struct __next_fn final { + _LIBCPP_FUNCTION_LIKE(__next_fn); template _LIBCPP_HIDE_FROM_ABI @@ -75,7 +74,7 @@ } }; -inline constexpr auto next = __next_fn(__function_like::__tag()); +inline constexpr auto next = __next_fn(__next_fn::__tag()); } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__iterator/prev.h b/libcxx/include/__iterator/prev.h --- a/libcxx/include/__iterator/prev.h +++ b/libcxx/include/__iterator/prev.h @@ -41,9 +41,8 @@ #if !defined(_LIBCPP_HAS_NO_RANGES) namespace ranges { -struct __prev_fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __prev_fn(__tag __x) noexcept : __function_like(__x) {} +struct __prev_fn final { + _LIBCPP_FUNCTION_LIKE(__prev_fn); template _LIBCPP_HIDE_FROM_ABI @@ -67,7 +66,7 @@ } }; -inline constexpr auto prev = __prev_fn(__function_like::__tag()); +inline constexpr auto prev = __prev_fn(__prev_fn::__tag()); } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) 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 --- 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 @@ -10,12 +10,6 @@ // UNSUPPORTED: libcpp-no-concepts // UNSUPPORTED: gcc-10 -// Clang has a bug when modules are enabled that causes `__function_like::operator&` -// not to be picked up by the derived class. -// XFAIL: clang-11 && modules-build -// XFAIL: clang-12 && modules-build -// XFAIL: clang-13 && modules-build - // ranges::next #include 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 --- 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 @@ -10,12 +10,6 @@ // UNSUPPORTED: libcpp-no-concepts // UNSUPPORTED: gcc-10 -// Clang has a bug when modules are enabled that causes `__function_like::operator&` -// not to be picked up by the derived class. -// XFAIL: clang-11 && modules-build -// XFAIL: clang-12 && modules-build -// XFAIL: clang-13 && modules-build - // ranges::prev #include