xref: /freebsd-src/contrib/llvm-project/libcxx/include/__ranges/empty.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1fe6060f1SDimitry Andric // -*- C++ -*-
2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
3fe6060f1SDimitry Andric //
4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7fe6060f1SDimitry Andric //
8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
9*bdd1243dSDimitry Andric 
10fe6060f1SDimitry Andric #ifndef _LIBCPP___RANGES_EMPTY_H
11fe6060f1SDimitry Andric #define _LIBCPP___RANGES_EMPTY_H
12fe6060f1SDimitry Andric 
1304eeddc0SDimitry Andric #include <__concepts/class_or_enum.h>
14fe6060f1SDimitry Andric #include <__config>
15fe6060f1SDimitry Andric #include <__iterator/concepts.h>
16fe6060f1SDimitry Andric #include <__ranges/access.h>
17fe6060f1SDimitry Andric #include <__ranges/size.h>
18fe6060f1SDimitry Andric 
19fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20fe6060f1SDimitry Andric #  pragma GCC system_header
21fe6060f1SDimitry Andric #endif
22fe6060f1SDimitry Andric 
23fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
24fe6060f1SDimitry Andric 
25*bdd1243dSDimitry Andric #if _LIBCPP_STD_VER > 17
26fe6060f1SDimitry Andric 
27fe6060f1SDimitry Andric // [range.prim.empty]
280eae32dcSDimitry Andric 
290eae32dcSDimitry Andric namespace ranges {
30fe6060f1SDimitry Andric namespace __empty {
31fe6060f1SDimitry Andric   template <class _Tp>
3204eeddc0SDimitry Andric   concept __member_empty =
3304eeddc0SDimitry Andric     __workaround_52970<_Tp> &&
3404eeddc0SDimitry Andric     requires(_Tp&& __t) {
350eae32dcSDimitry Andric       bool(__t.empty());
36fe6060f1SDimitry Andric     };
37fe6060f1SDimitry Andric 
38fe6060f1SDimitry Andric   template<class _Tp>
39fe6060f1SDimitry Andric   concept __can_invoke_size =
40fe6060f1SDimitry Andric     !__member_empty<_Tp> &&
410eae32dcSDimitry Andric     requires(_Tp&& __t) { ranges::size(__t); };
42fe6060f1SDimitry Andric 
43fe6060f1SDimitry Andric   template <class _Tp>
44fe6060f1SDimitry Andric   concept __can_compare_begin_end =
45fe6060f1SDimitry Andric     !__member_empty<_Tp> &&
46fe6060f1SDimitry Andric     !__can_invoke_size<_Tp> &&
47fe6060f1SDimitry Andric     requires(_Tp&& __t) {
48fe6060f1SDimitry Andric       bool(ranges::begin(__t) == ranges::end(__t));
49fe6060f1SDimitry Andric       { ranges::begin(__t) } -> forward_iterator;
50fe6060f1SDimitry Andric     };
51fe6060f1SDimitry Andric 
52fe6060f1SDimitry Andric   struct __fn {
53fe6060f1SDimitry Andric     template <__member_empty _Tp>
54fe6060f1SDimitry Andric     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
55fe6060f1SDimitry Andric         noexcept(noexcept(bool(__t.empty()))) {
560eae32dcSDimitry Andric       return bool(__t.empty());
57fe6060f1SDimitry Andric     }
58fe6060f1SDimitry Andric 
59fe6060f1SDimitry Andric     template <__can_invoke_size _Tp>
60fe6060f1SDimitry Andric     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
610eae32dcSDimitry Andric         noexcept(noexcept(ranges::size(__t))) {
620eae32dcSDimitry Andric       return ranges::size(__t) == 0;
63fe6060f1SDimitry Andric     }
64fe6060f1SDimitry Andric 
65fe6060f1SDimitry Andric     template<__can_compare_begin_end _Tp>
66fe6060f1SDimitry Andric     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
67fe6060f1SDimitry Andric         noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) {
68fe6060f1SDimitry Andric       return ranges::begin(__t) == ranges::end(__t);
69fe6060f1SDimitry Andric     }
70fe6060f1SDimitry Andric   };
711fd87a68SDimitry Andric } // namespace __empty
72fe6060f1SDimitry Andric 
73fe6060f1SDimitry Andric inline namespace __cpo {
74fe6060f1SDimitry Andric   inline constexpr auto empty = __empty::__fn{};
75fe6060f1SDimitry Andric } // namespace __cpo
76fe6060f1SDimitry Andric } // namespace ranges
77fe6060f1SDimitry Andric 
78*bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER > 17
79fe6060f1SDimitry Andric 
80fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
81fe6060f1SDimitry Andric 
82fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_EMPTY_H
83