Back to home page

EIC code displayed by LXR

 
 

    


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

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_MISMATCH_HPP
0014 #define RANGES_V3_ALGORITHM_MISMATCH_HPP
0015 
0016 #include <utility>
0017 
0018 #include <meta/meta.hpp>
0019 
0020 #include <range/v3/range_fwd.hpp>
0021 
0022 #include <range/v3/algorithm/result_types.hpp>
0023 #include <range/v3/functional/comparisons.hpp>
0024 #include <range/v3/functional/identity.hpp>
0025 #include <range/v3/functional/invoke.hpp>
0026 #include <range/v3/iterator/concepts.hpp>
0027 #include <range/v3/iterator/traits.hpp>
0028 #include <range/v3/range/access.hpp>
0029 #include <range/v3/range/concepts.hpp>
0030 #include <range/v3/range/dangling.hpp>
0031 #include <range/v3/range/traits.hpp>
0032 #include <range/v3/utility/static_const.hpp>
0033 
0034 #include <range/v3/detail/prologue.hpp>
0035 
0036 namespace ranges
0037 {
0038     /// \addtogroup group-algorithms
0039     /// @{
0040     template<typename I1, typename I2>
0041     using mismatch_result = detail::in1_in2_result<I1, I2>;
0042 
0043     RANGES_FUNC_BEGIN(mismatch)
0044 
0045         /// \brief function template \c mismatch
0046         template(typename I1,
0047                      typename S1,
0048                      typename I2,
0049                      typename C = equal_to,
0050                      typename P1 = identity,
0051                      typename P2 = identity)(
0052             requires input_iterator<I1> AND sentinel_for<S1, I1> AND
0053                 input_iterator<I2> AND
0054                 indirect_relation<C, projected<I1, P1>, projected<I2, P2>>)
0055         RANGES_DEPRECATED(
0056             "Use the variant of ranges::mismatch that takes an upper bound for "
0057             "both sequences")
0058         mismatch_result<I1, I2> RANGES_FUNC(mismatch)(I1 begin1,
0059                                                       S1 end1,
0060                                                       I2 begin2,
0061                                                       C pred = C{},
0062                                                       P1 proj1 = P1{},
0063                                                       P2 proj2 = P2{}) //
0064         {
0065             for(; begin1 != end1; ++begin1, ++begin2)
0066                 if(!invoke(pred, invoke(proj1, *begin1), invoke(proj2, *begin2)))
0067                     break;
0068             return {begin1, begin2};
0069         }
0070 
0071         /// \overload
0072         template(typename I1,
0073                      typename S1,
0074                      typename I2,
0075                      typename S2,
0076                      typename C = equal_to,
0077                      typename P1 = identity,
0078                      typename P2 = identity)(
0079             requires input_iterator<I1> AND sentinel_for<S1, I1> AND
0080                 input_iterator<I2> AND sentinel_for<S2, I2> AND
0081                 indirect_relation<C, projected<I1, P1>, projected<I2, P2>>)
0082         constexpr mismatch_result<I1, I2> RANGES_FUNC(mismatch)(I1 begin1,
0083                                                                 S1 end1,
0084                                                                 I2 begin2,
0085                                                                 S2 end2,
0086                                                                 C pred = C{},
0087                                                                 P1 proj1 = P1{},
0088                                                                 P2 proj2 = P2{}) //
0089         {
0090             for(; begin1 != end1 && begin2 != end2; ++begin1, ++begin2)
0091                 if(!invoke(pred, invoke(proj1, *begin1), invoke(proj2, *begin2)))
0092                     break;
0093             return {begin1, begin2};
0094         }
0095 
0096         /// \overload
0097         template(typename Rng1,
0098                      typename I2Ref,
0099                      typename C = equal_to,
0100                      typename P1 = identity,
0101                      typename P2 = identity)( //s
0102             requires input_range<Rng1> AND input_iterator<uncvref_t<I2Ref>> AND
0103                 indirect_relation<C,
0104                                   projected<iterator_t<Rng1>, P1>,
0105                                   projected<uncvref_t<I2Ref>, P2>>)
0106         RANGES_DEPRECATED(
0107             "Use the variant of ranges::mismatch that takes an upper bound for "
0108             "both sequences")
0109         mismatch_result<borrowed_iterator_t<Rng1>, uncvref_t<I2Ref>>
0110         RANGES_FUNC(mismatch)(Rng1 && rng1,
0111                               I2Ref && begin2,
0112                               C pred = C{}, // see below [*]
0113                               P1 proj1 = P1{},
0114                               P2 proj2 = P2{}) //
0115         {
0116             RANGES_DIAGNOSTIC_PUSH
0117             RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
0118             return (*this)(begin(rng1),
0119                            end(rng1),
0120                            static_cast<uncvref_t<I2Ref> &&>(begin2),
0121                            std::move(pred),
0122                            std::move(proj1),
0123                            std::move(proj2));
0124             RANGES_DIAGNOSTIC_POP
0125         }
0126 
0127         /// \overload
0128         template(typename Rng1,
0129                      typename Rng2,
0130                      typename C = equal_to,
0131                      typename P1 = identity,
0132                      typename P2 = identity)(
0133             requires input_range<Rng1> AND input_range<Rng2> AND
0134                 indirect_relation<C,
0135                                   projected<iterator_t<Rng1>, P1>,
0136                                   projected<iterator_t<Rng2>, P2>>)
0137         constexpr mismatch_result<borrowed_iterator_t<Rng1>, borrowed_iterator_t<Rng2>> //
0138         RANGES_FUNC(mismatch)(Rng1 && rng1,
0139                               Rng2 && rng2,
0140                               C pred = C{},
0141                               P1 proj1 = P1{},
0142                               P2 proj2 = P2{}) //
0143         {
0144             return (*this)(begin(rng1),
0145                            end(rng1),
0146                            begin(rng2),
0147                            end(rng2),
0148                            std::move(pred),
0149                            std::move(proj1),
0150                            std::move(proj2));
0151         }
0152 
0153     RANGES_FUNC_END(mismatch)
0154 
0155     namespace cpp20
0156     {
0157         using ranges::mismatch;
0158         using ranges::mismatch_result;
0159     } // namespace cpp20
0160 
0161     // [*] In this case, the 'begin2' iterator is taken by universal reference. Why? So
0162     // that we can properly distinguish this case:
0163     //   int x[] = {1,2,3,4};
0164     //   int y[] = {1,2,3,4};
0165     //   mismatch(x, y);
0166     // Had 'begin2' been taken by value as is customary, this call could match as either
0167     // two ranges, or a range and an iterator, where the iterator is the array, decayed
0168     // to a pointer. Yuk!
0169 
0170     /// @}
0171 } // namespace ranges
0172 
0173 #include <range/v3/detail/epilogue.hpp>
0174 
0175 #endif