Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:27:53

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-algorithms
0036     /// @{
0037 
0038     /// \cond
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     } // namespace detail
0052     /// \endcond
0053 
0054     RANGES_FUNC_BEGIN(equal)
0055 
0056         /// \brief function template \c equal
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         /// \overload
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         /// \overload
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         /// \overload
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 } // namespace ranges
0172 
0173 #include <range/v3/detail/epilogue.hpp>
0174 
0175 #endif