Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:07

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_VECTOR_HPP_INCLUDED
0009 #define CATCH_MATCHERS_VECTOR_HPP_INCLUDED
0010 
0011 #include <catch2/matchers/catch_matchers.hpp>
0012 #include <catch2/catch_approx.hpp>
0013 
0014 #include <algorithm>
0015 
0016 namespace Catch {
0017 namespace Matchers {
0018 
0019     template<typename T, typename Alloc>
0020     class VectorContainsElementMatcher final : public MatcherBase<std::vector<T, Alloc>> {
0021         T const& m_comparator;
0022 
0023     public:
0024         VectorContainsElementMatcher(T const& comparator):
0025             m_comparator(comparator)
0026         {}
0027 
0028         bool match(std::vector<T, Alloc> const& v) const override {
0029             for (auto const& el : v) {
0030                 if (el == m_comparator) {
0031                     return true;
0032                 }
0033             }
0034             return false;
0035         }
0036 
0037         std::string describe() const override {
0038             return "Contains: " + ::Catch::Detail::stringify( m_comparator );
0039         }
0040     };
0041 
0042     template<typename T, typename AllocComp, typename AllocMatch>
0043     class ContainsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0044         std::vector<T, AllocComp> const& m_comparator;
0045 
0046     public:
0047         ContainsMatcher(std::vector<T, AllocComp> const& comparator):
0048             m_comparator( comparator )
0049         {}
0050 
0051         bool match(std::vector<T, AllocMatch> const& v) const override {
0052             // !TBD: see note in EqualsMatcher
0053             if (m_comparator.size() > v.size())
0054                 return false;
0055             for (auto const& comparator : m_comparator) {
0056                 auto present = false;
0057                 for (const auto& el : v) {
0058                     if (el == comparator) {
0059                         present = true;
0060                         break;
0061                     }
0062                 }
0063                 if (!present) {
0064                     return false;
0065                 }
0066             }
0067             return true;
0068         }
0069         std::string describe() const override {
0070             return "Contains: " + ::Catch::Detail::stringify( m_comparator );
0071         }
0072     };
0073 
0074     template<typename T, typename AllocComp, typename AllocMatch>
0075     class EqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0076         std::vector<T, AllocComp> const& m_comparator;
0077 
0078     public:
0079         EqualsMatcher(std::vector<T, AllocComp> const& comparator):
0080             m_comparator( comparator )
0081         {}
0082 
0083         bool match(std::vector<T, AllocMatch> const& v) const override {
0084             // !TBD: This currently works if all elements can be compared using !=
0085             // - a more general approach would be via a compare template that defaults
0086             // to using !=. but could be specialised for, e.g. std::vector<T> etc
0087             // - then just call that directly
0088             if ( m_comparator.size() != v.size() ) { return false; }
0089             for ( std::size_t i = 0; i < v.size(); ++i ) {
0090                 if ( !( m_comparator[i] == v[i] ) ) { return false; }
0091             }
0092             return true;
0093         }
0094         std::string describe() const override {
0095             return "Equals: " + ::Catch::Detail::stringify( m_comparator );
0096         }
0097     };
0098 
0099     template<typename T, typename AllocComp, typename AllocMatch>
0100     class ApproxMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0101         std::vector<T, AllocComp> const& m_comparator;
0102         mutable Catch::Approx approx = Catch::Approx::custom();
0103 
0104     public:
0105         ApproxMatcher(std::vector<T, AllocComp> const& comparator):
0106             m_comparator( comparator )
0107         {}
0108 
0109         bool match(std::vector<T, AllocMatch> const& v) const override {
0110             if (m_comparator.size() != v.size())
0111                 return false;
0112             for (std::size_t i = 0; i < v.size(); ++i)
0113                 if (m_comparator[i] != approx(v[i]))
0114                     return false;
0115             return true;
0116         }
0117         std::string describe() const override {
0118             return "is approx: " + ::Catch::Detail::stringify( m_comparator );
0119         }
0120         template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
0121         ApproxMatcher& epsilon( T const& newEpsilon ) {
0122             approx.epsilon(static_cast<double>(newEpsilon));
0123             return *this;
0124         }
0125         template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
0126         ApproxMatcher& margin( T const& newMargin ) {
0127             approx.margin(static_cast<double>(newMargin));
0128             return *this;
0129         }
0130         template <typename = std::enable_if_t<std::is_constructible<double, T>::value>>
0131         ApproxMatcher& scale( T const& newScale ) {
0132             approx.scale(static_cast<double>(newScale));
0133             return *this;
0134         }
0135     };
0136 
0137     template<typename T, typename AllocComp, typename AllocMatch>
0138     class UnorderedEqualsMatcher final : public MatcherBase<std::vector<T, AllocMatch>> {
0139         std::vector<T, AllocComp> const& m_target;
0140 
0141     public:
0142         UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target):
0143             m_target(target)
0144         {}
0145         bool match(std::vector<T, AllocMatch> const& vec) const override {
0146             if (m_target.size() != vec.size()) {
0147                 return false;
0148             }
0149             return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
0150         }
0151 
0152         std::string describe() const override {
0153             return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
0154         }
0155     };
0156 
0157 
0158     // The following functions create the actual matcher objects.
0159     // This allows the types to be inferred
0160 
0161     //! Creates a matcher that matches vectors that contain all elements in `comparator`
0162     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0163     ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
0164         return ContainsMatcher<T, AllocComp, AllocMatch>(comparator);
0165     }
0166 
0167     //! Creates a matcher that matches vectors that contain `comparator` as an element
0168     template<typename T, typename Alloc = std::allocator<T>>
0169     VectorContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
0170         return VectorContainsElementMatcher<T, Alloc>(comparator);
0171     }
0172 
0173     //! Creates a matcher that matches vectors that are exactly equal to `comparator`
0174     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0175     EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
0176         return EqualsMatcher<T, AllocComp, AllocMatch>(comparator);
0177     }
0178 
0179     //! Creates a matcher that matches vectors that `comparator` as an element
0180     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0181     ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
0182         return ApproxMatcher<T, AllocComp, AllocMatch>(comparator);
0183     }
0184 
0185     //! Creates a matcher that matches vectors that is equal to `target` modulo permutation
0186     template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
0187     UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
0188         return UnorderedEqualsMatcher<T, AllocComp, AllocMatch>(target);
0189     }
0190 
0191 } // namespace Matchers
0192 } // namespace Catch
0193 
0194 #endif // CATCH_MATCHERS_VECTOR_HPP_INCLUDED