brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 3621bda Raw
201 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H10#define _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H11 12#include <__algorithm/ranges_equal.h>13#include <__algorithm/ranges_starts_with.h>14#include <__config>15#include <__functional/identity.h>16#include <__functional/ranges_operations.h>17#include <__functional/reference_wrapper.h>18#include <__iterator/advance.h>19#include <__iterator/concepts.h>20#include <__iterator/distance.h>21#include <__iterator/indirectly_comparable.h>22#include <__iterator/reverse_iterator.h>23#include <__ranges/access.h>24#include <__ranges/concepts.h>25#include <__ranges/size.h>26#include <__utility/move.h>27 28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)29#  pragma GCC system_header30#endif31 32_LIBCPP_PUSH_MACROS33#include <__undef_macros>34 35#if _LIBCPP_STD_VER >= 2336 37_LIBCPP_BEGIN_NAMESPACE_STD38 39namespace ranges {40struct __ends_with {41  template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>42  _LIBCPP_HIDE_FROM_ABI static constexpr bool __ends_with_fn_impl_bidirectional(43      _Iter1 __first1,44      _Sent1 __last1,45      _Iter2 __first2,46      _Sent2 __last2,47      _Pred& __pred,48      _Proj1& __proj1,49      _Proj2& __proj2) {50    auto __rbegin1 = std::make_reverse_iterator(__last1);51    auto __rend1   = std::make_reverse_iterator(__first1);52    auto __rbegin2 = std::make_reverse_iterator(__last2);53    auto __rend2   = std::make_reverse_iterator(__first2);54    return ranges::starts_with(55        __rbegin1, __rend1, __rbegin2, __rend2, std::ref(__pred), std::ref(__proj1), std::ref(__proj2));56  }57 58  template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>59  _LIBCPP_HIDE_FROM_ABI static constexpr bool __ends_with_fn_impl(60      _Iter1 __first1,61      _Sent1 __last1,62      _Iter2 __first2,63      _Sent2 __last2,64      _Pred& __pred,65      _Proj1& __proj1,66      _Proj2& __proj2) {67    if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> &&68                  (!std::random_access_iterator<_Sent1>) && (!std::random_access_iterator<_Sent2>)) {69      return __ends_with_fn_impl_bidirectional(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);70 71    } else {72      auto __n1 = ranges::distance(__first1, __last1);73      auto __n2 = ranges::distance(__first2, __last2);74      if (__n2 == 0)75        return true;76      if (__n2 > __n1)77        return false;78 79      return __ends_with_fn_impl_with_offset(80          std::move(__first1),81          std::move(__last1),82          std::move(__first2),83          std::move(__last2),84          __pred,85          __proj1,86          __proj2,87          __n1 - __n2);88    }89  }90 91  template <class _Iter1,92            class _Sent1,93            class _Iter2,94            class _Sent2,95            class _Pred,96            class _Proj1,97            class _Proj2,98            class _Offset>99  static _LIBCPP_HIDE_FROM_ABI constexpr bool __ends_with_fn_impl_with_offset(100      _Iter1 __first1,101      _Sent1 __last1,102      _Iter2 __first2,103      _Sent2 __last2,104      _Pred& __pred,105      _Proj1& __proj1,106      _Proj2& __proj2,107      _Offset __offset) {108    if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> &&109                  !std::random_access_iterator<_Sent1> && !std::random_access_iterator<_Sent2>) {110      return __ends_with_fn_impl_bidirectional(111          std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);112 113    } else {114      ranges::advance(__first1, __offset);115      return ranges::equal(116          std::move(__first1),117          std::move(__last1),118          std::move(__first2),119          std::move(__last2),120          std::ref(__pred),121          std::ref(__proj1),122          std::ref(__proj2));123    }124  }125 126  template <input_iterator _Iter1,127            sentinel_for<_Iter1> _Sent1,128            input_iterator _Iter2,129            sentinel_for<_Iter2> _Sent2,130            class _Pred  = ranges::equal_to,131            class _Proj1 = identity,132            class _Proj2 = identity>133    requires(forward_iterator<_Iter1> || sized_sentinel_for<_Sent1, _Iter1>) &&134            (forward_iterator<_Iter2> || sized_sentinel_for<_Sent2, _Iter2>) &&135            indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>136  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(137      _Iter1 __first1,138      _Sent1 __last1,139      _Iter2 __first2,140      _Sent2 __last2,141      _Pred __pred   = {},142      _Proj1 __proj1 = {},143      _Proj2 __proj2 = {}) const {144    return __ends_with_fn_impl(145        std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);146  }147 148  template <input_range _Range1,149            input_range _Range2,150            class _Pred  = ranges::equal_to,151            class _Proj1 = identity,152            class _Proj2 = identity>153    requires(forward_range<_Range1> || sized_range<_Range1>) && (forward_range<_Range2> || sized_range<_Range2>) &&154            indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>155  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(156      _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {157    if constexpr (sized_range<_Range1> && sized_range<_Range2>) {158      auto __n1 = ranges::size(__range1);159      auto __n2 = ranges::size(__range2);160      if (__n2 == 0)161        return true;162      if (__n2 > __n1)163        return false;164      auto __offset = __n1 - __n2;165 166      return __ends_with_fn_impl_with_offset(167          ranges::begin(__range1),168          ranges::end(__range1),169          ranges::begin(__range2),170          ranges::end(__range2),171          __pred,172          __proj1,173          __proj2,174          __offset);175 176    } else {177      return __ends_with_fn_impl(178          ranges::begin(__range1),179          ranges::end(__range1),180          ranges::begin(__range2),181          ranges::end(__range2),182          __pred,183          __proj1,184          __proj2);185    }186  }187};188 189inline namespace __cpo {190inline constexpr auto ends_with = __ends_with{};191} // namespace __cpo192} // namespace ranges193 194_LIBCPP_END_NAMESPACE_STD195 196#endif // _LIBCPP_STD_VER >= 23197 198_LIBCPP_POP_MACROS199 200#endif // _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H201