Home | History | Annotate | Line # | Download | only in __ranges
      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