1 1.1 joerg // -*- C++ -*- 2 1.1 joerg //===----------------------------------------------------------------------===// 3 1.1 joerg // 4 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 6 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 1.1 joerg // 8 1.1 joerg //===----------------------------------------------------------------------===// 9 1.1 joerg #ifndef _LIBCPP___RANGES_EMPTY_H 10 1.1 joerg #define _LIBCPP___RANGES_EMPTY_H 11 1.1 joerg 12 1.1 joerg #include <__config> 13 1.1 joerg #include <__iterator/concepts.h> 14 1.1 joerg #include <__ranges/size.h> 15 1.1 joerg #include <type_traits> 16 1.1 joerg 17 1.1 joerg #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 1.1 joerg #pragma GCC system_header 19 1.1 joerg #endif 20 1.1 joerg 21 1.1 joerg _LIBCPP_PUSH_MACROS 22 1.1 joerg #include <__undef_macros> 23 1.1 joerg 24 1.1 joerg _LIBCPP_BEGIN_NAMESPACE_STD 25 1.1 joerg 26 1.1 joerg #if !defined(_LIBCPP_HAS_NO_RANGES) 27 1.1 joerg 28 1.1 joerg // clang-format off 29 1.1 joerg namespace ranges { 30 1.1 joerg // [range.prim.empty] 31 1.1 joerg namespace __empty { 32 1.1 joerg template <class _Tp> 33 1.1 joerg concept __member_empty = requires(_Tp&& __t) { 34 1.1 joerg bool(_VSTD::forward<_Tp>(__t).empty()); 35 1.1 joerg }; 36 1.1 joerg 37 1.1 joerg template<class _Tp> 38 1.1 joerg concept __can_invoke_size = 39 1.1 joerg !__member_empty<_Tp> && 40 1.1 joerg requires(_Tp&& __t) { ranges::size(_VSTD::forward<_Tp>(__t)); }; 41 1.1 joerg 42 1.1 joerg template <class _Tp> 43 1.1 joerg concept __can_compare_begin_end = 44 1.1 joerg !__member_empty<_Tp> && 45 1.1 joerg !__can_invoke_size<_Tp> && 46 1.1 joerg requires(_Tp&& __t) { 47 1.1 joerg bool(ranges::begin(__t) == ranges::end(__t)); 48 1.1 joerg { ranges::begin(__t) } -> forward_iterator; 49 1.1 joerg }; 50 1.1 joerg 51 1.1 joerg struct __fn { 52 1.1 joerg template <__member_empty _Tp> 53 1.1 joerg [[nodiscard]] constexpr bool operator()(_Tp&& __t) const 54 1.1 joerg noexcept(noexcept(bool(__t.empty()))) { 55 1.1 joerg return __t.empty(); 56 1.1 joerg } 57 1.1 joerg 58 1.1 joerg template <__can_invoke_size _Tp> 59 1.1 joerg [[nodiscard]] constexpr bool operator()(_Tp&& __t) const 60 1.1 joerg noexcept(noexcept(ranges::size(_VSTD::forward<_Tp>(__t)))) { 61 1.1 joerg return ranges::size(_VSTD::forward<_Tp>(__t)) == 0; 62 1.1 joerg } 63 1.1 joerg 64 1.1 joerg template<__can_compare_begin_end _Tp> 65 1.1 joerg [[nodiscard]] constexpr bool operator()(_Tp&& __t) const 66 1.1 joerg noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) { 67 1.1 joerg return ranges::begin(__t) == ranges::end(__t); 68 1.1 joerg } 69 1.1 joerg }; 70 1.1 joerg } 71 1.1 joerg 72 1.1 joerg inline namespace __cpo { 73 1.1 joerg inline constexpr auto empty = __empty::__fn{}; 74 1.1 joerg } // namespace __cpo 75 1.1 joerg } // namespace ranges 76 1.1 joerg // clang-format off 77 1.1 joerg 78 1.1 joerg #endif // !defined(_LIBCPP_HAS_NO_RANGES) 79 1.1 joerg 80 1.1 joerg _LIBCPP_END_NAMESPACE_STD 81 1.1 joerg 82 1.1 joerg _LIBCPP_POP_MACROS 83 1.1 joerg 84 1.1 joerg #endif // _LIBCPP___RANGES_EMPTY_H 85