xref: /openbsd-src/gnu/llvm/libcxx/include/__ranges/empty.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
176d0caaeSpatrick // -*- C++ -*-
276d0caaeSpatrick //===----------------------------------------------------------------------===//
376d0caaeSpatrick //
476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information.
676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
776d0caaeSpatrick //
876d0caaeSpatrick //===----------------------------------------------------------------------===//
9*4bdff4beSrobert 
1076d0caaeSpatrick #ifndef _LIBCPP___RANGES_EMPTY_H
1176d0caaeSpatrick #define _LIBCPP___RANGES_EMPTY_H
1276d0caaeSpatrick 
13*4bdff4beSrobert #include <__concepts/class_or_enum.h>
1476d0caaeSpatrick #include <__config>
1576d0caaeSpatrick #include <__iterator/concepts.h>
1676d0caaeSpatrick #include <__ranges/access.h>
1776d0caaeSpatrick #include <__ranges/size.h>
1876d0caaeSpatrick 
1976d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2076d0caaeSpatrick #  pragma GCC system_header
2176d0caaeSpatrick #endif
2276d0caaeSpatrick 
2376d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD
2476d0caaeSpatrick 
25*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
2676d0caaeSpatrick 
2776d0caaeSpatrick // [range.prim.empty]
28*4bdff4beSrobert 
29*4bdff4beSrobert namespace ranges {
3076d0caaeSpatrick namespace __empty {
3176d0caaeSpatrick   template <class _Tp>
32*4bdff4beSrobert   concept __member_empty =
33*4bdff4beSrobert     __workaround_52970<_Tp> &&
requires(_Tp && __t)34*4bdff4beSrobert     requires(_Tp&& __t) {
35*4bdff4beSrobert       bool(__t.empty());
3676d0caaeSpatrick     };
3776d0caaeSpatrick 
3876d0caaeSpatrick   template<class _Tp>
3976d0caaeSpatrick   concept __can_invoke_size =
4076d0caaeSpatrick     !__member_empty<_Tp> &&
41*4bdff4beSrobert     requires(_Tp&& __t) { ranges::size(__t); };
4276d0caaeSpatrick 
4376d0caaeSpatrick   template <class _Tp>
4476d0caaeSpatrick   concept __can_compare_begin_end =
4576d0caaeSpatrick     !__member_empty<_Tp> &&
4676d0caaeSpatrick     !__can_invoke_size<_Tp> &&
4776d0caaeSpatrick     requires(_Tp&& __t) {
4876d0caaeSpatrick       bool(ranges::begin(__t) == ranges::end(__t));
4976d0caaeSpatrick       { ranges::begin(__t) } -> forward_iterator;
5076d0caaeSpatrick     };
5176d0caaeSpatrick 
5276d0caaeSpatrick   struct __fn {
5376d0caaeSpatrick     template <__member_empty _Tp>
operator__fn5476d0caaeSpatrick     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
5576d0caaeSpatrick         noexcept(noexcept(bool(__t.empty()))) {
56*4bdff4beSrobert       return bool(__t.empty());
5776d0caaeSpatrick     }
5876d0caaeSpatrick 
5976d0caaeSpatrick     template <__can_invoke_size _Tp>
operator__fn6076d0caaeSpatrick     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
61*4bdff4beSrobert         noexcept(noexcept(ranges::size(__t))) {
62*4bdff4beSrobert       return ranges::size(__t) == 0;
6376d0caaeSpatrick     }
6476d0caaeSpatrick 
6576d0caaeSpatrick     template<__can_compare_begin_end _Tp>
operator__fn6676d0caaeSpatrick     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
6776d0caaeSpatrick         noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) {
6876d0caaeSpatrick       return ranges::begin(__t) == ranges::end(__t);
6976d0caaeSpatrick     }
7076d0caaeSpatrick   };
71*4bdff4beSrobert } // namespace __empty
7276d0caaeSpatrick 
7376d0caaeSpatrick inline namespace __cpo {
7476d0caaeSpatrick   inline constexpr auto empty = __empty::__fn{};
7576d0caaeSpatrick } // namespace __cpo
7676d0caaeSpatrick } // namespace ranges
7776d0caaeSpatrick 
78*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17
7976d0caaeSpatrick 
8076d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD
8176d0caaeSpatrick 
8276d0caaeSpatrick #endif // _LIBCPP___RANGES_EMPTY_H
83