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