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