1 /*
2  *  Created by Phil Nash on 21/02/2017.
3  *  Copyright (c) 2017 Two Blue Cubes Ltd. All rights reserved.
4  *
5  * Distributed under the Boost Software License, Version 1.0. (See accompanying
6  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
9 #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
10 
11 #include "catch_matchers.hpp"
12 
13 namespace Catch {
14 namespace Matchers {
15 
16     namespace Vector {
17 
18         template<typename T>
19         struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
20 
ContainsElementMatcherContainsElementMatcher21             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
22 
matchContainsElementMatcher23             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
24                 return std::find(v.begin(), v.end(), m_comparator) != v.end();
25             }
26 
describeContainsElementMatcher27             virtual std::string describe() const CATCH_OVERRIDE {
28                 return "Contains: " + Catch::toString( m_comparator );
29             }
30 
31             T const& m_comparator;
32         };
33 
34         template<typename T>
35         struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
36 
ContainsMatcherContainsMatcher37             ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
38 
matchContainsMatcher39             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
40                 // !TBD: see note in EqualsMatcher
41                 if (m_comparator.size() > v.size())
42                     return false;
43                 for (size_t i = 0; i < m_comparator.size(); ++i)
44                     if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
45                         return false;
46                 return true;
47             }
describeContainsMatcher48             virtual std::string describe() const CATCH_OVERRIDE {
49                 return "Contains: " + Catch::toString( m_comparator );
50             }
51 
52             std::vector<T> const& m_comparator;
53         };
54 
55         template<typename T>
56         struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
57 
EqualsMatcherEqualsMatcher58             EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
59 
matchEqualsMatcher60             bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
61                 // !TBD: This currently works if all elements can be compared using !=
62                 // - a more general approach would be via a compare template that defaults
63                 // to using !=. but could be specialised for, e.g. std::vector<T> etc
64                 // - then just call that directly
65                 if (m_comparator.size() != v.size())
66                     return false;
67                 for (size_t i = 0; i < v.size(); ++i)
68                     if (m_comparator[i] != v[i])
69                         return false;
70                 return true;
71             }
describeEqualsMatcher72             virtual std::string describe() const CATCH_OVERRIDE {
73                 return "Equals: " + Catch::toString( m_comparator );
74             }
75             std::vector<T> const& m_comparator;
76         };
77 
78     } // namespace Vector
79 
80     // The following functions create the actual matcher objects.
81     // This allows the types to be inferred
82 
83     template<typename T>
Contains(std::vector<T> const & comparator)84     Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
85         return Vector::ContainsMatcher<T>( comparator );
86     }
87 
88     template<typename T>
VectorContains(T const & comparator)89     Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
90         return Vector::ContainsElementMatcher<T>( comparator );
91     }
92 
93     template<typename T>
Equals(std::vector<T> const & comparator)94     Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
95         return Vector::EqualsMatcher<T>( comparator );
96     }
97 
98 } // namespace Matchers
99 } // namespace Catch
100 
101 #endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
102