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