mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	| @@ -10,10 +10,33 @@ | ||||
|  | ||||
| #include "catch_matchers.h" | ||||
|  | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
|  | ||||
|     namespace Vector { | ||||
|         namespace Detail { | ||||
|             template <typename InputIterator, typename T> | ||||
|             size_t count(InputIterator first, InputIterator last, T const& item) { | ||||
|                 size_t cnt = 0; | ||||
|                 for (; first != last; ++first) { | ||||
|                     if (*first == item) { | ||||
|                         ++cnt; | ||||
|                     } | ||||
|                 } | ||||
|                 return cnt; | ||||
|             } | ||||
|             template <typename InputIterator, typename T> | ||||
|             bool contains(InputIterator first, InputIterator last, T const& item) { | ||||
|                 for (; first != last; ++first) { | ||||
|                     if (*first == item) { | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         template<typename T> | ||||
|         struct ContainsElementMatcher : MatcherBase<std::vector<T>> { | ||||
| @@ -89,6 +112,46 @@ namespace Matchers { | ||||
|             std::vector<T> const& m_comparator; | ||||
|         }; | ||||
|  | ||||
|         template<typename T> | ||||
|         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> { | ||||
|             UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {} | ||||
|             bool match(std::vector<T> const& vec) const override { | ||||
|                 // Note: This is a reimplementation of std::is_permutation, | ||||
|                 //       because I don't want to include <algorithm> inside the common path | ||||
|                 if (m_target.size() != vec.size()) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 auto lfirst = m_target.begin(), llast = m_target.end(); | ||||
|                 auto rfirst = vec.begin(), rlast = vec.end(); | ||||
|                 // Cut common prefix to optimize checking of permuted parts | ||||
|                 while (lfirst != llast && *lfirst != *rfirst) { | ||||
|                     ++lfirst; ++rfirst; | ||||
|                 } | ||||
|                 if (lfirst == llast) { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 for (auto mid = lfirst; mid != llast; ++mid) { | ||||
|                     // Skip already counted items | ||||
|                     if (Detail::contains(lfirst, mid, *mid)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     size_t num_vec = Detail::count(rfirst, rlast, *mid); | ||||
|                     if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             std::string describe() const override { | ||||
|                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); | ||||
|             } | ||||
|         private: | ||||
|             std::vector<T> const& m_target; | ||||
|         }; | ||||
|  | ||||
|     } // namespace Vector | ||||
|  | ||||
|     // The following functions create the actual matcher objects. | ||||
| @@ -109,6 +172,11 @@ namespace Matchers { | ||||
|         return Vector::EqualsMatcher<T>( comparator ); | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) { | ||||
|         return Vector::UnorderedEqualsMatcher<T>(target); | ||||
|     } | ||||
|  | ||||
| } // namespace Matchers | ||||
| } // namespace Catch | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Martin Hořeňovský
					Martin Hořeňovský