empty.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. #include <__concepts/class_or_enum.h>
  12. #include <__config>
  13. #include <__iterator/concepts.h>
  14. #include <__ranges/access.h>
  15. #include <__ranges/size.h>
  16. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  17. # pragma GCC system_header
  18. #endif
  19. _LIBCPP_BEGIN_NAMESPACE_STD
  20. #if _LIBCPP_STD_VER >= 20
  21. // [range.prim.empty]
  22. namespace ranges {
  23. namespace __empty {
  24. template <class _Tp>
  25. concept __member_empty = __workaround_52970<_Tp> && requires(_Tp&& __t) { bool(__t.empty()); };
  26. template <class _Tp>
  27. concept __can_invoke_size = !__member_empty<_Tp> && requires(_Tp&& __t) { ranges::size(__t); };
  28. template <class _Tp>
  29. concept __can_compare_begin_end = !__member_empty<_Tp> && !__can_invoke_size<_Tp> && requires(_Tp&& __t) {
  30. bool(ranges::begin(__t) == ranges::end(__t));
  31. { ranges::begin(__t) } -> forward_iterator;
  32. };
  33. struct __fn {
  34. template <__member_empty _Tp>
  35. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const noexcept(noexcept(bool(__t.empty()))) {
  36. return bool(__t.empty());
  37. }
  38. template <__can_invoke_size _Tp>
  39. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const noexcept(noexcept(ranges::size(__t))) {
  40. return ranges::size(__t) == 0;
  41. }
  42. template <__can_compare_begin_end _Tp>
  43. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
  44. noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) {
  45. return ranges::begin(__t) == ranges::end(__t);
  46. }
  47. };
  48. } // namespace __empty
  49. inline namespace __cpo {
  50. inline constexpr auto empty = __empty::__fn{};
  51. } // namespace __cpo
  52. } // namespace ranges
  53. #endif // _LIBCPP_STD_VER >= 20
  54. _LIBCPP_END_NAMESPACE_STD
  55. #endif // _LIBCPP___RANGES_EMPTY_H