diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -181,7 +181,6 @@ __format/formatter_integral.h __format/formatter_string.h __format/parser_std_format_spec.h - __function_like.h __functional/binary_function.h __functional/binary_negate.h __functional/bind.h diff --git a/libcxx/include/__function_like.h b/libcxx/include/__function_like.h deleted file mode 100644 --- a/libcxx/include/__function_like.h +++ /dev/null @@ -1,51 +0,0 @@ -// -*- 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_FUNCTION_LIKE_H -#define _LIBCPP___ITERATOR_FUNCTION_LIKE_H - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_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. -// -// Since these are still standard library functions, we use `__function_like` to eliminate most of -// 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 - -#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 @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> @@ -72,7 +71,7 @@ namespace ranges { namespace __advance { -struct __fn final : private __function_like { +struct __fn { private: template _LIBCPP_HIDE_FROM_ABI @@ -99,8 +98,6 @@ } public: - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template _LIBCPP_HIDE_FROM_ABI @@ -191,7 +188,7 @@ } // namespace __advance inline namespace __cpo { - inline constexpr auto advance = __advance::__fn(__function_like::__tag()); + inline constexpr auto advance = __advance::__fn{}; } // namespace __cpo } // namespace 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 @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -43,10 +42,7 @@ namespace ranges { namespace __next { -struct __fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -79,7 +75,7 @@ } // namespace __next inline namespace __cpo { - inline constexpr auto next = __next::__fn(__function_like::__tag()); + inline constexpr auto next = __next::__fn{}; } // namespace __cpo } // namespace 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 @@ -12,7 +12,6 @@ #include <__config> #include <__debug> -#include <__function_like.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -42,10 +41,7 @@ namespace ranges { namespace __prev { -struct __fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { @@ -71,7 +67,7 @@ } // namespace __prev inline namespace __cpo { - inline constexpr auto prev = __prev::__fn(__function_like::__tag()); + inline constexpr auto prev = __prev::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/__memory/ranges_construct_at.h b/libcxx/include/__memory/ranges_construct_at.h --- a/libcxx/include/__memory/ranges_construct_at.h +++ b/libcxx/include/__memory/ranges_construct_at.h @@ -12,7 +12,6 @@ #include <__concepts/destructible.h> #include <__config> -#include <__function_like.h> #include <__iterator/incrementable_traits.h> #include <__iterator/readable_traits.h> #include <__memory/concepts.h> @@ -37,9 +36,7 @@ namespace __construct_at { -struct __fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template()) _Tp(declval<_Args>()...) )> @@ -52,16 +49,14 @@ } // namespace __construct_at inline namespace __cpo { - inline constexpr auto construct_at = __construct_at::__fn(__function_like::__tag()); + inline constexpr auto construct_at = __construct_at::__fn{}; } // namespace __cpo // destroy_at namespace __destroy_at { -struct __fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp* __location) const noexcept { @@ -72,16 +67,14 @@ } // namespace __destroy_at inline namespace __cpo { - inline constexpr auto destroy_at = __destroy_at::__fn(__function_like::__tag()); + inline constexpr auto destroy_at = __destroy_at::__fn{}; } // namespace __cpo // destroy namespace __destroy { -struct __fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_input_iterator _InputIterator, __nothrow_sentinel_for<_InputIterator> _Sentinel> requires destructible> _LIBCPP_HIDE_FROM_ABI @@ -100,16 +93,14 @@ } // namespace __destroy inline namespace __cpo { - inline constexpr auto destroy = __destroy::__fn(__function_like::__tag()); + inline constexpr auto destroy = __destroy::__fn{}; } // namespace __cpo // destroy_n namespace __destroy_n { -struct __fn final : private __function_like { - _LIBCPP_HIDE_FROM_ABI constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_input_iterator _InputIterator> requires destructible> _LIBCPP_HIDE_FROM_ABI @@ -121,10 +112,11 @@ } // namespace __destroy_n inline namespace __cpo { - inline constexpr auto destroy_n = __destroy_n::__fn(__function_like::__tag()); + inline constexpr auto destroy_n = __destroy_n::__fn{}; } // namespace __cpo } // namespace ranges + #endif // !defined(_LIBCPP_HAS_NO_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h --- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h +++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h @@ -13,7 +13,6 @@ #include <__algorithm/in_out_result.h> #include <__concepts/constructible.h> #include <__config> -#include <__function_like.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> @@ -40,9 +39,7 @@ namespace __uninitialized_default_construct { -struct __fn final : private __function_like { - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel> requires default_initializable> @@ -62,16 +59,14 @@ } // namespace __uninitialized_default_construct inline namespace __cpo { - inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{}; } // namespace __cpo // uninitialized_default_construct_n namespace __uninitialized_default_construct_n { -struct __fn final : private __function_like { - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator> requires default_initializable> _ForwardIterator operator()(_ForwardIterator __first, @@ -84,18 +79,14 @@ } // namespace __uninitialized_default_construct_n inline namespace __cpo { - inline constexpr auto uninitialized_default_construct_n = - __uninitialized_default_construct_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{}; } // namespace __cpo // uninitialized_value_construct namespace __uninitialized_value_construct { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel> requires default_initializable> @@ -110,24 +101,19 @@ borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { return (*this)(ranges::begin(__range), ranges::end(__range)); } - }; } // namespace __uninitialized_value_construct inline namespace __cpo { - inline constexpr auto uninitialized_value_construct = - __uninitialized_value_construct::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct::__fn{}; } // namespace __cpo // uninitialized_value_construct_n namespace __uninitialized_value_construct_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator> requires default_initializable> _ForwardIterator operator()(_ForwardIterator __first, @@ -135,24 +121,19 @@ using _ValueType = remove_reference_t>; return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); } - }; } // namespace __uninitialized_value_construct_n inline namespace __cpo { - inline constexpr auto uninitialized_value_construct_n = - __uninitialized_value_construct_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n::__fn{}; } // namespace __cpo // uninitialized_fill namespace __uninitialized_fill { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel, class _Tp> @@ -167,23 +148,19 @@ borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const { return (*this)(ranges::begin(__range), ranges::end(__range), __x); } - }; } // namespace __uninitialized_fill inline namespace __cpo { - inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{}; } // namespace __cpo // uninitialized_fill_n namespace __uninitialized_fill_n { -struct __fn final : private __function_like { - - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template <__nothrow_forward_iterator _ForwardIterator, class _Tp> requires constructible_from, const _Tp&> _ForwardIterator operator()(_ForwardIterator __first, @@ -192,13 +169,12 @@ using _ValueType = remove_reference_t>; return _VSTD::__uninitialized_fill_n<_ValueType>(_VSTD::move(__first), __n, __x); } - }; } // namespace __uninitialized_fill_n inline namespace __cpo { - inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{}; } // namespace __cpo // uninitialized_copy @@ -208,9 +184,7 @@ namespace __uninitialized_copy { -struct __fn final : private __function_like { - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _Sentinel1, __nothrow_forward_iterator _OutputIterator, @@ -237,7 +211,7 @@ } // namespace __uninitialized_copy inline namespace __cpo { - inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{}; } // namespace __cpo // uninitialized_copy_n @@ -247,9 +221,7 @@ namespace __uninitialized_copy_n { -struct __fn final : private __function_like { - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _Sentinel> @@ -267,7 +239,7 @@ } // namespace __uninitialized_copy_n inline namespace __cpo { - inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn{}; } // namespace __cpo // uninitialized_move @@ -277,9 +249,7 @@ namespace __uninitialized_move { -struct __fn final : private __function_like { - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _Sentinel1, __nothrow_forward_iterator _OutputIterator, @@ -289,7 +259,6 @@ operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { using _ValueType = remove_reference_t>; auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; - auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; @@ -307,7 +276,7 @@ } // namespace __uninitialized_move inline namespace __cpo { - inline constexpr auto uninitialized_move = __uninitialized_move::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_move = __uninitialized_move::__fn{}; } // namespace __cpo // uninitialized_move_n @@ -317,9 +286,7 @@ namespace __uninitialized_move_n { -struct __fn final : private __function_like { - constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} - +struct __fn { template _Sentinel> @@ -329,9 +296,8 @@ _OutputIterator __ofirst, _Sentinel __olast) const { using _ValueType = remove_reference_t>; auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; - - auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), - _VSTD::move(__olast), __iter_move); + auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, + _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; } }; @@ -339,7 +305,7 @@ } // namespace __uninitialized_move_n inline namespace __cpo { - inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn(__function_like::__tag()); + inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -591,10 +591,7 @@ module __iterator { module access { private header "__iterator/access.h" } - module advance { - private header "__iterator/advance.h" - export __function_like - } + module advance { private header "__iterator/advance.h" } module back_insert_iterator { private header "__iterator/back_insert_iterator.h" } module common_iterator { private header "__iterator/common_iterator.h" } module concepts { private header "__iterator/concepts.h" } @@ -615,16 +612,10 @@ module iterator { private header "__iterator/iterator.h" } module iterator_traits { private header "__iterator/iterator_traits.h" } module move_iterator { private header "__iterator/move_iterator.h" } - module next { - private header "__iterator/next.h" - export __function_like - } + module next { private header "__iterator/next.h" } module ostream_iterator { private header "__iterator/ostream_iterator.h" } module ostreambuf_iterator { private header "__iterator/ostreambuf_iterator.h" } - module prev { - private header "__iterator/prev.h" - export __function_like - } + module prev { private header "__iterator/prev.h" } module projected { private header "__iterator/projected.h" } module readable_traits { private header "__iterator/readable_traits.h" } module reverse_access { private header "__iterator/reverse_access.h" } @@ -672,14 +663,8 @@ module concepts { private header "__memory/concepts.h" } module construct_at { private header "__memory/construct_at.h" } module pointer_traits { private header "__memory/pointer_traits.h" } - module ranges_construct_at { - private header "__memory/ranges_construct_at.h" - export __function_like - } - module ranges_uninitialized_algorithms { - private header "__memory/ranges_uninitialized_algorithms.h" - export __function_like - } + module ranges_construct_at { private header "__memory/ranges_construct_at.h" } + module ranges_uninitialized_algorithms { private header "__memory/ranges_uninitialized_algorithms.h" } module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } module shared_ptr { private header "__memory/shared_ptr.h" } module temporary_buffer { private header "__memory/temporary_buffer.h" } @@ -986,7 +971,6 @@ module __bits { private header "__bits" export * } module __debug { header "__debug" export * } module __errc { private header "__errc" export * } - module __function_like { private header "__function_like.h" export * } module __hash_table { header "__hash_table" export * } module __locale { private header "__locale" export * } module __mbstate { private header "__mbstate_t.h" export * } diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/function_like.h.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/function_like.h.module.verify.cpp deleted file mode 100644 --- a/libcxx/test/libcxx/diagnostics/detail.headers/function_like.h.module.verify.cpp +++ /dev/null @@ -1,15 +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 -// -//===----------------------------------------------------------------------===// - -// 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: '__function_like.h'}} -#include <__function_like.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 deleted file mode 100644 --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/special_function.compile.pass.cpp +++ /dev/null @@ -1,23 +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 -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: libcpp-no-concepts - -// ranges::advance - -#include - -#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 different mechanism to achieve this effect, so this check is -// libc++-specific. -LIBCPP_STATIC_ASSERT(std::is_class_v); -LIBCPP_STATIC_ASSERT(is_niebloid()); 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 deleted file mode 100644 --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/special_function.compile.pass.cpp +++ /dev/null @@ -1,23 +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 -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: libcpp-no-concepts - -// ranges::next - -#include - -#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 different mechanism to achieve this effect, so this check is -// libc++-specific. -LIBCPP_STATIC_ASSERT(std::is_class_v); -LIBCPP_STATIC_ASSERT(is_niebloid()); 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 deleted file mode 100644 --- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.prev/special_function.compile.pass.cpp +++ /dev/null @@ -1,23 +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 -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17 -// UNSUPPORTED: libcpp-no-concepts - -// ranges::prev - -#include - -#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 different mechanism to achieve this effect, so this check is -// libc++-specific. -LIBCPP_STATIC_ASSERT(std::is_class_v); -LIBCPP_STATIC_ASSERT(is_niebloid()); diff --git a/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp @@ -0,0 +1,185 @@ +//===----------------------------------------------------------------------===// +// +// 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, libcpp-has-no-incomplete-ranges +// REQUIRES: stdlib=libc++ + +// [algorithms.requirements]/2 +// [range.iter.ops.general]/2 + +#include +#include +#include +#include +#include + +// Niebloids, unlike CPOs, are *not* required to be semiregular or even to have +// a declared type at all; they are specified as "magic" overload sets whose +// names are not found by argument-dependent lookup and which inhibit +// argument-dependent lookup if they are found via a `using`-declaration. +// +// libc++ implements them using the same function-object technique we use for CPOs; +// therefore this file should stay in sync with ./cpo.compile.pass.cpp. + +template +constexpr bool test(CPO& o, Args&&...) { + static_assert(std::is_class_v); + static_assert(std::is_trivial_v); + + auto p = o; + using T = decltype(p); + + // The type of a customization point object, ignoring cv-qualifiers, shall model semiregular. + static_assert(std::semiregular); + + // The type T of a customization point object, ignoring cv-qualifiers, shall model... + static_assert(std::invocable); + static_assert(std::invocable); + static_assert(std::invocable); + static_assert(std::invocable); + + return true; +} + +int *p; +int a[10]; +//auto odd = [](int x) { return x % 2 != 0; }; +//auto triple = [](int x) { return 3*x; }; +//auto plus = [](int x, int y) { return x == y; }; +//std::mt19937 g; + +// [algorithm.syn] + +//static_assert(test(std::ranges::adjacent_find, a)); +//static_assert(test(std::ranges::all_of, a, odd)); +//static_assert(test(std::ranges::any_of, a, odd)); +//static_assert(test(std::ranges::binary_search, a, 42)); +//static_assert(test(std::ranges::clamp, 42, 42, 42)); +//static_assert(test(std::ranges::copy, a, a)); +//static_assert(test(std::ranges::copy_backward, a, a)); +//static_assert(test(std::ranges::copy_if, a, a, odd)); +//static_assert(test(std::ranges::copy_n, a, 10, a)); +//static_assert(test(std::ranges::count, a, 42)); +//static_assert(test(std::ranges::count_if, a, odd)); +//static_assert(test(std::ranges::ends_with, a, a)); +//static_assert(test(std::ranges::equal, a, a)); +//static_assert(test(std::ranges::equal_range, a, 42)); +//static_assert(test(std::ranges::fill, a, 42)); +//static_assert(test(std::ranges::fill_n, a, 10, 42)); +//static_assert(test(std::ranges::find, a, 42)); +//static_assert(test(std::ranges::find_end, a, a)); +//static_assert(test(std::ranges::find_first_of, a, a)); +//static_assert(test(std::ranges::find_if, a, odd)); +//static_assert(test(std::ranges::find_if_not, a, odd)); +//static_assert(test(std::ranges::for_each, a, odd)); +//static_assert(test(std::ranges::for_each_n, a, 10, odd)); +//static_assert(test(std::ranges::generate, a, 42)); +//static_assert(test(std::ranges::generate_n, a, 10, 42)); +//static_assert(test(std::ranges::includes, a, a)); +//static_assert(test(std::ranges::inplace_merge, a, a+5)); +//static_assert(test(std::ranges::is_heap, a)); +//static_assert(test(std::ranges::is_heap_until, a)); +//static_assert(test(std::ranges::is_partitioned, a, odd)); +//static_assert(test(std::ranges::is_permutation, a, a)); +//static_assert(test(std::ranges::is_sorted, a)); +//static_assert(test(std::ranges::is_sorted_until, a)); +//static_assert(test(std::ranges::lexicographical_compare, a, a)); +//static_assert(test(std::ranges::lower_bound, a, 42)); +//static_assert(test(std::ranges::make_heap, a)); +//static_assert(test(std::ranges::max, a)); +//static_assert(test(std::ranges::max_element, a)); +//static_assert(test(std::ranges::merge, a, a, a)); +//static_assert(test(std::ranges::min, a)); +//static_assert(test(std::ranges::min_element, a)); +//static_assert(test(std::ranges::minmax, a)); +//static_assert(test(std::ranges::minmax_element, a)); +//static_assert(test(std::ranges::mismatch, a, a)); +//static_assert(test(std::ranges::move, a, a)); +//static_assert(test(std::ranges::move_backward, a, a)); +//static_assert(test(std::ranges::next_permutation, a)); +//static_assert(test(std::ranges::none_of, a, odd)); +//static_assert(test(std::ranges::nth_element, a, a+5)); +//static_assert(test(std::ranges::partial_sort, a, a+5)); +//static_assert(test(std::ranges::partial_sort_copy, a, a)); +//static_assert(test(std::ranges::partition, a, odd)); +//static_assert(test(std::ranges::partition_copy, a, a, a, odd)); +//static_assert(test(std::ranges::partition_point, a, odd)); +//static_assert(test(std::ranges::pop_heap, a)); +//static_assert(test(std::ranges::prev_permutation, a)); +//static_assert(test(std::ranges::push_heap, a)); +//static_assert(test(std::ranges::remove, a, 42)); +//static_assert(test(std::ranges::remove_copy, a, a, 42)); +//static_assert(test(std::ranges::remove_copy_if, a, a, odd)); +//static_assert(test(std::ranges::remove_if, a, odd)); +//static_assert(test(std::ranges::replace, a, 42, 43)); +//static_assert(test(std::ranges::replace_copy, a, a, 42, 43)); +//static_assert(test(std::ranges::replace_copy_if, a, a, odd, 43)); +//static_assert(test(std::ranges::replace_if, a, odd, 43)); +//static_assert(test(std::ranges::reverse, a)); +//static_assert(test(std::ranges::reverse_copy, a, a)); +//static_assert(test(std::ranges::rotate, a, a+5)); +//static_assert(test(std::ranges::rotate_copy, a, a+5, a)); +//static_assert(test(std::ranges::sample, a, a, 5)); +//static_assert(test(std::ranges::search, a, a)); +//static_assert(test(std::ranges::search_n, a, 10, 42)); +//static_assert(test(std::ranges::set_difference, a, a, a)); +//static_assert(test(std::ranges::set_intersection, a, a, a)); +//static_assert(test(std::ranges::set_symmetric_difference, a, a, a)); +//static_assert(test(std::ranges::set_union, a, a, a)); +//static_assert(test(std::ranges::shuffle, a, g)); +//static_assert(test(std::ranges::sort, a)); +//static_assert(test(std::ranges::sort_heap, a)); +//static_assert(test(std::ranges::stable_partition, a, odd)); +//static_assert(test(std::ranges::stable_sort, a)); +//static_assert(test(std::ranges::starts_with, a, a)); +//static_assert(test(std::ranges::swap_ranges, a, a)); +//static_assert(test(std::ranges::transform, a, a, triple)); +//static_assert(test(std::ranges::unique, a)); +//static_assert(test(std::ranges::unique_copy, a, a)); +//static_assert(test(std::ranges::upper_bound, a, 42)); + +// [memory.syn] + +static_assert(test(std::ranges::construct_at, a, 42)); +static_assert(test(std::ranges::destroy, a)); +static_assert(test(std::ranges::destroy, a, a+10)); +static_assert(test(std::ranges::destroy_at, a)); +static_assert(test(std::ranges::destroy_n, a, 10)); +static_assert(test(std::ranges::uninitialized_copy, a, a)); +static_assert(test(std::ranges::uninitialized_copy, a, a+10, a, a+10)); +static_assert(test(std::ranges::uninitialized_copy_n, a, 10, a, a+10)); +static_assert(test(std::ranges::uninitialized_default_construct, a)); +static_assert(test(std::ranges::uninitialized_default_construct, a, a+10)); +static_assert(test(std::ranges::uninitialized_default_construct_n, a, 10)); +static_assert(test(std::ranges::uninitialized_fill, a, 42)); +static_assert(test(std::ranges::uninitialized_fill, a, a+10, 42)); +static_assert(test(std::ranges::uninitialized_fill_n, a, 10, 42)); +static_assert(test(std::ranges::uninitialized_move, a, a)); +static_assert(test(std::ranges::uninitialized_move, a, a+10, a, a+10)); +static_assert(test(std::ranges::uninitialized_move_n, a, 10, a, a+10)); +static_assert(test(std::ranges::uninitialized_value_construct, a)); +static_assert(test(std::ranges::uninitialized_value_construct, a, a+10)); +static_assert(test(std::ranges::uninitialized_value_construct_n, a, 10)); + +// [numeric.ops.overview] currently has no ranges algorithms. See P1813, P2214 + +// [range.iter.ops] + +static_assert(test(std::ranges::advance, p, 5)); +static_assert(test(std::ranges::advance, p, 5, a+10)); +static_assert(test(std::ranges::advance, p, a+10)); +//static_assert(test(std::ranges::distance, a)); +//static_assert(test(std::ranges::distance, a, a+10)); +static_assert(test(std::ranges::next, a)); +static_assert(test(std::ranges::next, a, 5)); +static_assert(test(std::ranges::next, a, 5, a+10)); +static_assert(test(std::ranges::next, a, a+10)); +static_assert(test(std::ranges::prev, a+10)); +static_assert(test(std::ranges::prev, a+10, 5)); +static_assert(test(std::ranges::prev, a+10, 5, a));