2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___RANGES_EMPTY_H
11 #define _LIBCPP___RANGES_EMPTY_H
13 #include <__concepts/class_or_enum.h>
15 #include <__iterator/concepts.h>
16 #include <__ranges/access.h>
17 #include <__ranges/size.h>
19 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20 # pragma GCC system_header
23 _LIBCPP_BEGIN_NAMESPACE_STD
25 #if _LIBCPP_STD_VER >= 20
32 concept __member_empty
= requires(_Tp
&& __t
) { bool(__t
.empty()); };
35 concept __can_invoke_size
= !__member_empty
<_Tp
> && requires(_Tp
&& __t
) { ranges::size(__t
); };
38 concept __can_compare_begin_end
= !__member_empty
<_Tp
> && !__can_invoke_size
<_Tp
> && requires(_Tp
&& __t
) {
39 bool(ranges::begin(__t
) == ranges::end(__t
));
40 { ranges::begin(__t
) } -> forward_iterator
;
44 template <__member_empty _Tp
>
45 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr bool operator()(_Tp
&& __t
) const noexcept(noexcept(bool(__t
.empty()))) {
46 return bool(__t
.empty());
49 template <__can_invoke_size _Tp
>
50 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr bool operator()(_Tp
&& __t
) const noexcept(noexcept(ranges::size(__t
))) {
51 return ranges::size(__t
) == 0;
54 template <__can_compare_begin_end _Tp
>
55 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr bool operator()(_Tp
&& __t
) const
56 noexcept(noexcept(bool(ranges::begin(__t
) == ranges::end(__t
)))) {
57 return ranges::begin(__t
) == ranges::end(__t
);
60 } // namespace __empty
62 inline namespace __cpo
{
63 inline constexpr auto empty
= __empty::__fn
{};
67 #endif // _LIBCPP_STD_VER >= 20
69 _LIBCPP_END_NAMESPACE_STD
71 #endif // _LIBCPP___RANGES_EMPTY_H