Solche IteratorRange
wird in den meisten Fällen funktionieren - zur Begrenzung Blick in Matcher Körper:
TEST(A,A)
{
int a,b,c;
std::vector<int> values{ a,b,c };
MyMock m;
EXPECT_CALL(m, f(_,_,_,_)).With(Args<1,2>(IteratorRange(ContainerEq(values))));
m.f(X{}, values.begin(), values.end(), Y{});
}
[UPDATE]
:
MATCHER_P(IteratorRange, param, "")
{
auto begin = get<0>(arg);
auto end = get<1>(arg);
// these two lines might be weak point of this matcher implementation...
// I mean:
// 1. constructing vector might be not supported
// e.g. object are not copyable)
// 2. copying objects from range might "change" the tested code behavior
// e.g. copy is badly implemented
// 3. it is for sure "performance" degradation
using value_type = typename std::iterator_traits<decltype(begin)>::value_type;
std::vector<value_type> range{begin, end};
Matcher<decltype(range)> matcher = param;
return matcher.MatchAndExplain(range, result_listener);
}
Es kann wie folgt verwendet werden
Die Überwindung der Nachteile dieser Inte rnal Kopieren eines Bereichs in den Behälter - Sie brauchen das Licht Behälter zu erfinden - wie diese:
template <typename Iterator>
class RangeView
{
public:
using iterator = Iterator;
using const_iterator = Iterator;
using value_type = typename std::iterator_traits<Iterator>::value_type;
RangeView(Iterator begin, Iterator end) : beginIter(begin), endIter(end) {}
iterator begin() const { return beginIter; }
iterator end() const { return endIter; }
std::size_t size() const { return std::distance(beginIter, endIter); }
bool operator == (const RangeView& other) const
{
return size() == other.size() && std::equal(beginIter, endIter, other.beginIter);
}
private:
Iterator beginIter, endIter;
};
plus einige Hilfsfunktion zu erleichtern, diese Klasse zu verwenden:
template <typename Iterator>
void PrintTo(RangeView<Iterator> const& range, std::ostream* os)
{
*os << "{";
for (auto&& e: range) *os << "[" << PrintToString(e) << "]";
*os << "}";
}
template <typename Iterator>
RangeView<Iterator> makeRangeView(Iterator begin, Iterator end)
{
return RangeView<Iterator>(begin, end);
}
template <typename Container>
auto makeRangeView(Container const& container)
{
return makeRangeView(std::begin(container), std::end(container));
}
Beachten Sie, wenn Sie Verwenden Sie Boost in Ihrem Projekt - Sie können range from boost verwenden - Sie müssen "das Rad nicht neu erfinden".
Dann - Licht Matcher ohne diese Nachteile definiert werden:
MATCHER_P(IteratorRangeLight, param, "")
{
auto begin = get<0>(arg);
auto end = get<1>(arg);
auto range = makeRangeView(begin, end);
Matcher<decltype(range)> matcher = param;
return matcher.MatchAndExplain(range, result_listener);
}
Dann - es ist wie folgt verwenden:
TEST(A,A)
{
int a=1,b=2,c=3;
std::vector<int> values{ a,b,c };
MyMock m;
EXPECT_CALL(m, f(_,_,_,_)).
With(Args<1,2>(IteratorRangeLight(ContainerEq(makeRangeView(values)))));
// ^^^^^^^^^^^^^
// note that you need to use makeRangeView also within the matcher
m.f(X{}, values.begin(), values.end(), Y{});
}
Gibt es eine Möglichkeit, die Googlemock zu machen Matcher für 'boost :: Reichweite? Das könnte die notwendige Brücke liefern ... – SimonD