File indexing completed on 2025-12-16 10:27:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RANGES_V3_ALGORITHM_EQUAL_HPP
0014 #define RANGES_V3_ALGORITHM_EQUAL_HPP
0015
0016 #include <utility>
0017
0018 #include <range/v3/range_fwd.hpp>
0019
0020 #include <range/v3/functional/comparisons.hpp>
0021 #include <range/v3/functional/identity.hpp>
0022 #include <range/v3/functional/invoke.hpp>
0023 #include <range/v3/iterator/concepts.hpp>
0024 #include <range/v3/iterator/operations.hpp>
0025 #include <range/v3/iterator/traits.hpp>
0026 #include <range/v3/range/access.hpp>
0027 #include <range/v3/range/concepts.hpp>
0028 #include <range/v3/range/traits.hpp>
0029 #include <range/v3/utility/static_const.hpp>
0030
0031 #include <range/v3/detail/prologue.hpp>
0032
0033 namespace ranges
0034 {
0035
0036
0037
0038
0039 namespace detail
0040 {
0041 template<typename I0, typename S0, typename I1, typename S1, typename C,
0042 typename P0, typename P1>
0043 constexpr bool equal_nocheck(I0 begin0, S0 end0, I1 begin1, S1 end1, C pred,
0044 P0 proj0, P1 proj1)
0045 {
0046 for(; begin0 != end0 && begin1 != end1; ++begin0, ++begin1)
0047 if(!invoke(pred, invoke(proj0, *begin0), invoke(proj1, *begin1)))
0048 return false;
0049 return begin0 == end0 && begin1 == end1;
0050 }
0051 }
0052
0053
0054 RANGES_FUNC_BEGIN(equal)
0055
0056
0057 template(typename I0,
0058 typename S0,
0059 typename I1,
0060 typename C = equal_to,
0061 typename P0 = identity,
0062 typename P1 = identity)(
0063 requires input_iterator<I0> AND sentinel_for<S0, I0> AND
0064 input_iterator<I1> AND indirectly_comparable<I0, I1, C, P0, P1>)
0065 RANGES_DEPRECATED(
0066 "Use the variant of ranges::equal that takes an upper bound for "
0067 "both sequences")
0068 constexpr bool RANGES_FUNC(equal)(I0 begin0,
0069 S0 end0,
0070 I1 begin1,
0071 C pred = C{},
0072 P0 proj0 = P0{},
0073 P1 proj1 = P1{})
0074 {
0075 for(; begin0 != end0; ++begin0, ++begin1)
0076 if(!invoke(pred, invoke(proj0, *begin0), invoke(proj1, *begin1)))
0077 return false;
0078 return true;
0079 }
0080
0081
0082 template(typename I0,
0083 typename S0,
0084 typename I1,
0085 typename S1,
0086 typename C = equal_to,
0087 typename P0 = identity,
0088 typename P1 = identity)(
0089 requires input_iterator<I0> AND sentinel_for<S0, I0> AND
0090 input_iterator<I1> AND sentinel_for<S1, I1> AND
0091 indirectly_comparable<I0, I1, C, P0, P1>)
0092 constexpr bool RANGES_FUNC(equal)(I0 begin0,
0093 S0 end0,
0094 I1 begin1,
0095 S1 end1,
0096 C pred = C{},
0097 P0 proj0 = P0{},
0098 P1 proj1 = P1{})
0099 {
0100 if(RANGES_CONSTEXPR_IF(sized_sentinel_for<S0, I0> &&
0101 sized_sentinel_for<S1, I1>))
0102 if(distance(begin0, end0) != distance(begin1, end1))
0103 return false;
0104 return detail::equal_nocheck(std::move(begin0),
0105 std::move(end0),
0106 std::move(begin1),
0107 std::move(end1),
0108 std::move(pred),
0109 std::move(proj0),
0110 std::move(proj1));
0111 }
0112
0113
0114 template(typename Rng0,
0115 typename I1Ref,
0116 typename C = equal_to,
0117 typename P0 = identity,
0118 typename P1 = identity)(
0119 requires input_range<Rng0> AND input_iterator<uncvref_t<I1Ref>> AND
0120 indirectly_comparable<iterator_t<Rng0>, uncvref_t<I1Ref>, C, P0, P1>)
0121 RANGES_DEPRECATED(
0122 "Use the variant of ranges::equal that takes an upper bound for "
0123 "both sequences")
0124 constexpr bool RANGES_FUNC(equal)(Rng0 && rng0,
0125 I1Ref && begin1,
0126 C pred = C{},
0127 P0 proj0 = P0{},
0128 P1 proj1 = P1{})
0129 {
0130 RANGES_DIAGNOSTIC_PUSH
0131 RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
0132 return (*this)(begin(rng0),
0133 end(rng0),
0134 (I1Ref &&) begin1,
0135 std::move(pred),
0136 std::move(proj0),
0137 std::move(proj1));
0138 RANGES_DIAGNOSTIC_POP
0139 }
0140
0141
0142 template(typename Rng0,
0143 typename Rng1,
0144 typename C = equal_to,
0145 typename P0 = identity,
0146 typename P1 = identity)(
0147 requires input_range<Rng0> AND input_range<Rng1> AND
0148 indirectly_comparable<iterator_t<Rng0>, iterator_t<Rng1>, C, P0, P1>)
0149 constexpr bool RANGES_FUNC(equal)(
0150 Rng0 && rng0, Rng1 && rng1, C pred = C{}, P0 proj0 = P0{}, P1 proj1 = P1{})
0151 {
0152 if(RANGES_CONSTEXPR_IF(sized_range<Rng0> && sized_range<Rng1>))
0153 if(distance(rng0) != distance(rng1))
0154 return false;
0155 return detail::equal_nocheck(begin(rng0),
0156 end(rng0),
0157 begin(rng1),
0158 end(rng1),
0159 std::move(pred),
0160 std::move(proj0),
0161 std::move(proj1));
0162 }
0163
0164 RANGES_FUNC_END(equal)
0165
0166 namespace cpp20
0167 {
0168 using ranges::equal;
0169 }
0170
0171 }
0172
0173 #include <range/v3/detail/epilogue.hpp>
0174
0175 #endif