Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:54:36

0001 
0002 //              Copyright Catch2 Authors
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //   (See accompanying file LICENSE.txt or copy at
0005 //        https://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // SPDX-License-Identifier: BSL-1.0
0008 #ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
0009 #define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED
0010 
0011 #include <catch2/internal/catch_is_permutation.hpp>
0012 #include <catch2/matchers/catch_matchers_templated.hpp>
0013 
0014 #include <algorithm>
0015 #include <utility>
0016 
0017 namespace Catch {
0018     namespace Matchers {
0019 
0020         /**
0021          * Matcher for checking that an element contains the same
0022          * elements in the same order
0023          */
0024         template <typename TargetRangeLike, typename Equality>
0025         class RangeEqualsMatcher final : public MatcherGenericBase {
0026             TargetRangeLike m_desired;
0027             Equality m_predicate;
0028 
0029         public:
0030             template <typename TargetRangeLike2, typename Equality2>
0031             constexpr
0032             RangeEqualsMatcher( TargetRangeLike2&& range,
0033                                 Equality2&& predicate ):
0034                 m_desired( CATCH_FORWARD( range ) ),
0035                 m_predicate( CATCH_FORWARD( predicate ) ) {}
0036 
0037             template <typename RangeLike>
0038             constexpr
0039             bool match( RangeLike&& rng ) const {
0040                 auto rng_start = begin( rng );
0041                 const auto rng_end = end( rng );
0042                 auto target_start = begin( m_desired );
0043                 const auto target_end = end( m_desired );
0044 
0045                 while (rng_start != rng_end && target_start != target_end) {
0046                     if (!m_predicate(*rng_start, *target_start)) {
0047                         return false;
0048                     }
0049                     ++rng_start;
0050                     ++target_start;
0051                 }
0052                 return rng_start == rng_end && target_start == target_end;
0053             }
0054 
0055             std::string describe() const override {
0056                 return "elements are " + Catch::Detail::stringify( m_desired );
0057             }
0058         };
0059 
0060         /**
0061          * Matcher for checking that an element contains the same
0062          * elements (but not necessarily in the same order)
0063          */
0064         template <typename TargetRangeLike, typename Equality>
0065         class UnorderedRangeEqualsMatcher final : public MatcherGenericBase {
0066             TargetRangeLike m_desired;
0067             Equality m_predicate;
0068 
0069         public:
0070             template <typename TargetRangeLike2, typename Equality2>
0071             constexpr
0072             UnorderedRangeEqualsMatcher( TargetRangeLike2&& range,
0073                                          Equality2&& predicate ):
0074                 m_desired( CATCH_FORWARD( range ) ),
0075                 m_predicate( CATCH_FORWARD( predicate ) ) {}
0076 
0077             template <typename RangeLike>
0078             constexpr
0079             bool match( RangeLike&& rng ) const {
0080                 using std::begin;
0081                 using std::end;
0082                 return Catch::Detail::is_permutation( begin( m_desired ),
0083                                                       end( m_desired ),
0084                                                       begin( rng ),
0085                                                       end( rng ),
0086                                                       m_predicate );
0087             }
0088 
0089             std::string describe() const override {
0090                 return "unordered elements are " +
0091                        ::Catch::Detail::stringify( m_desired );
0092             }
0093         };
0094 
0095         /**
0096          * Creates a matcher that checks if all elements in a range are equal
0097          * to all elements in another range.
0098          *
0099          * Uses the provided predicate `predicate` to do the comparisons
0100          * (defaulting to `std::equal_to`)
0101          */
0102         template <typename RangeLike,
0103                   typename Equality = decltype( std::equal_to<>{} )>
0104         constexpr
0105         RangeEqualsMatcher<RangeLike, Equality>
0106         RangeEquals( RangeLike&& range,
0107                      Equality&& predicate = std::equal_to<>{} ) {
0108             return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
0109         }
0110 
0111         /**
0112          * Creates a matcher that checks if all elements in a range are equal
0113          * to all elements in an initializer list.
0114          *
0115          * Uses the provided predicate `predicate` to do the comparisons
0116          * (defaulting to `std::equal_to`)
0117          */
0118         template <typename T,
0119                   typename Equality = decltype( std::equal_to<>{} )>
0120         constexpr
0121         RangeEqualsMatcher<std::initializer_list<T>, Equality>
0122         RangeEquals( std::initializer_list<T> range,
0123                      Equality&& predicate = std::equal_to<>{} ) {
0124             return { range, CATCH_FORWARD( predicate ) };
0125         }
0126 
0127         /**
0128          * Creates a matcher that checks if all elements in a range are equal
0129          * to all elements in another range, in some permutation.
0130          *
0131          * Uses the provided predicate `predicate` to do the comparisons
0132          * (defaulting to `std::equal_to`)
0133          */
0134         template <typename RangeLike,
0135                   typename Equality = decltype( std::equal_to<>{} )>
0136         constexpr
0137         UnorderedRangeEqualsMatcher<RangeLike, Equality>
0138         UnorderedRangeEquals( RangeLike&& range,
0139                               Equality&& predicate = std::equal_to<>{} ) {
0140             return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) };
0141         }
0142 
0143         /**
0144          * Creates a matcher that checks if all elements in a range are equal
0145          * to all elements in an initializer list, in some permutation.
0146          *
0147          * Uses the provided predicate `predicate` to do the comparisons
0148          * (defaulting to `std::equal_to`)
0149          */
0150         template <typename T,
0151                   typename Equality = decltype( std::equal_to<>{} )>
0152         constexpr
0153         UnorderedRangeEqualsMatcher<std::initializer_list<T>, Equality>
0154         UnorderedRangeEquals( std::initializer_list<T> range,
0155                               Equality&& predicate = std::equal_to<>{} ) {
0156             return { range, CATCH_FORWARD( predicate ) };
0157         }
0158     } // namespace Matchers
0159 } // namespace Catch
0160 
0161 #endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED