Nested Matchers in GTest - c++

I would like to use some existing matchers in other matcher. I know about the MatcherInterface solution but I was wondering can I use matchers which were defined by MATCHER_P. If found this solution:
struct Foo
{
double x;
double y;
};
struct Bar
{
Foo foo;
int i;
};
MATCHER_P(EqFoo, foo, "")
{
::testing::Matcher<double> x_matcher = ::testing::DoubleNear(foo.x, 0.0001);
if (!x_matcher.MatchAndExplain(arg.x, result_listener))
{
return false;
}
::testing::Matcher<double> y_matcher = ::testing::DoubleNear(foo.y, 0.0001);
if (!y_matcher.MatchAndExplain(arg.y, result_listener))
{
return false;
}
return true;
}
MATCHER_P(EqBar, bar, "")
{
::testing::Matcher<Foo> foo_matcher = EqFooMatcherP<Foo>(bar.foo);
if (!foo_matcher.MatchAndExplain(arg.foo, result_listener))
{
return false;
}
if (bar.i != arg.i)
{
return false;
}
return true;
}
TEST_F(TestClass, BarTest)
{
Bar bar_val{{10.12, 76.43}, 78};
Bar bar_exp{{10.12, 99.99}, 78};
EXPECT_THAT(bar_val, EqBar(bar_exp));
}
I am just wondering, is there any better and nicer solution to
use my own MATCHER_P matcher in another one
use an original GTest matcher in another one.

The correct way is to use, as much as possible, the matchers from gtest/gmock. Only if there is no already provided matchers - use your own.
In your example - it is just as simple as this:
auto EqFoo(const Foo& expected)
{
return ::testing::AllOf(
::testing::Field(&Foo::x, ::testing::DoubleNear(expected.x, 0.0001)),
::testing::Field(&Foo::y, ::testing::DoubleNear(expected.y, 0.0001))
);
}
auto EqBar(const Bar& expected)
{
return ::testing::AllOf(
::testing::Field(&Bar::foo, EqFoo(expected.foo)),
::testing::Field(&Bar::i, expected.i)
);
}
More general approach is to use overloads:
auto MatchDouble(double expected)
{
return ::testing::DoubleNear(expected.x, 0.0001);
}
auto MatchFoo(::testing::Matcher<double> x, ::testing::Matcher<double> y)
{
return ::testing::AllOf(
::testing::Field(&Foo::x, x),
::testing::Field(&Foo::y, y)
);
}
auto MatchFoo(double x, double y)
{
return MatchFoo(MatchDouble(x), MatchDouble(y));
}
auto MatchBar(::testing::Matcher<Foo> foo, ::testing::Matcher<int> i)
{
return ::testing::AllOf(
::testing::Field(&Bar::foo, foo),
::testing::Field(&Bar::i, expected.i),
);
}
auto MatchBar(const Bar& expected)
{
return MatchBar(expected.foo, expected.i);
}
So your test:
TEST_F(TestClass, BarTest)
{
Bar bar_val{{10.12, 76.43}, 78};
Bar bar_exp{{10.12, 99.99}, 78};
EXPECT_THAT(bar_val, MatchBar(bar_exp));
// or - e.g. you can match only Bar::y if other things are irrelevant in your test
EXPECT_THAT(bar_val, MatchBar(MatchFoo(_, MatchDouble(2.001)), _);
}
Anyway - using MATCHER_P should be rather rare case, my own observation is that this macro is really overused.
In case your project is pre-C++14 - use ::testing::Matcher<T> instead of auto as return type for all of these functions.

Related

How does this default template struct assignment work? [duplicate]

This question already has answers here:
Arrow operator (->) in function heading
(3 answers)
Closed 4 months ago.
I have been digging into some embedded C++ firmware used by DaveJone's (eevblog) uSupply project
https://gitlab.com/eevblog/usupply-firmware.
There is common pattern of code that I just can't quite wrap my head around what is happening.
For example:
In the file "RegistersRCC.hpp" there is a template struct:
template <std::size_t A>
struct CR : public General::u32_reg<A>
{
using base_t = General::u32_reg<A>;
using base_t::base_t;
//PLL register bits
auto PLLRDY () { return base_t::template Actual<RCC_CR_PLLRDY>(); }
auto PLLON () { return base_t::template Actual<RCC_CR_PLLON>(); }
//PLL Management functions
void EnablePLL() noexcept
{
if ( not PLLON().Get() )
{
PLLON() = true;
while ( not PLLRDY().Get() );
}
}
void DisablePLL() noexcept
{
if ( PLLON().Get() )
{
PLLON() = false;
while ( PLLRDY().Get() );
}
}
//Enable clock security
auto CSSON () { return base_t::template Actual<RCC_CR_CSSON>(); }
//High speed external oscillator bits
auto HSEBYP () { return base_t::template Actual<RCC_CR_HSEBYP>(); }
auto HSERDY () { return base_t::template Actual<RCC_CR_HSERDY>(); }
auto HSEON () { return base_t::template Actual<RCC_CR_HSEON>(); }
//HSE Management functions
void EnableHSE()
{
if ( not HSEON().Get() )
{
HSEON() = true; //Enable the clock
while( not HSERDY().Get() ); //Wait for it to stable
}
}
void DisableHSE()
{
if ( HSEON().Get() )
{
HSEON() = false; //Disable the clock
while( HSERDY().Get() ); //Wait for it to disable
}
}
void ConnectHSE()
{
HSEBYP() = false; //Connect it to system
}
void BypassHSE()
{
HSEBYP() = true; //Disconnect it to system
}
//High speed internal oscillator bits
auto HSICAL () { return base_t::template Actual<RCC_CR_HSICAL>(); }
auto HSITRIM() { return base_t::template Actual<RCC_CR_HSITRIM>(); }
auto HSIRDY () { return base_t::template Actual<RCC_CR_HSIRDY>(); }
auto HSION () { return base_t::template Actual<RCC_CR_HSION>(); }
//HSI Management functions, No calibration provided
// these chips are factory calibrated
void EnableHSI()
{
if (not HSION().Get())
{
HSION() = true;
while (!HSIRDY());
}
}
void DisableHSI()
{
if ( HSION().Get() )
{
HSION() = false;
while (HSIRDY());
}
}
};
This struct exists in the namespace:
namespace Peripherals::RCCGeneral
{
}
Within the same namespace/header file there is this "Default"
CR() -> CR<RCC_BASE + offsetof(RCC_TypeDef, CR)>;
I think this is where my gap in understanding lies. What is happening here? Specifically with the lvalue and arrow operator, and why this is located within the header.
Within the files that utilize the RCCRegisters you see usages like:
CR{}.DisablePLL();
This is called class template argument deduction(CTAD) which allows writing deduction guides to the compiler about how to deduce the template arguments from constructor calls.
It is a handy C++17 addition that saves on typing:
std::vector x{1.,2.,3.} //deduces std::vector<double>
C++14 and older requires to explicitly write std::vector<double> which gets tedious and too verbose for some more complex examples.
In this case, the guide
CR() -> CR<RCC_BASE + offsetof(RCC_TypeDef, CR)>;
specifies that the default constructor should deduce A template parameter to RCC_BASE + offsetof(RCC_TypeDef, CR).
The same could have been achieved by simply using a default template argument:
template <std::size_t A = default_value>
struct CR : public General::u32_reg<A>{ ... };
But here comes the catch, offsetof(RCC_TypeDef, CR) is not valid here because at this line, CR doesn't exist yet.
So my assumption is this a fix around this limitation to allow making the default value depend on the class definition itself, quite clever I think.

Can I implement operator overloading for D's SumType alias?

TLDR: Is there a way make D's SumType play nice with opCmp while maintaining its functionality?
Context
I'm writing a program for which D's native SumType works almost completely. However, I would like to be able to do the following:
alias Foo = SumType!(int, string);
Foo x = 3;
Foo y = 5;
writeln(max(x, y));
However, since no ordering is natively defined for SumType, I receive the following error:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\comparison.d(1644): Error: static assert: "Invalid arguments: Cannot compare types SumType!(int, string) and SumType!(int, string) for ordering."
mwe.d(11): instantiated from here: `max!(SumType!(int, string), SumType!(int, string))`
I was able to remedy this specific issue using the following method:
import std.stdio : writeln;
import std.exception : assertThrown;
import std.algorithm.comparison : max;
import core.exception : AssertError;
import std.sumtype;
struct Foo {
SumType!(int, string) value;
this(T)(T v) {
value = v;
}
ref Atom opAssign(T)(T rhs) {
value = rhs;
return this;
}
int opCmp(Foo other) {
return match!(
(a, b) => a < b ? -1 : a == b ? 0 : 1,
(_1, _2) => assert(0, "Cannot match")
)(value, other.value);
}
}
void main() {
Foo x = 3;
Foo y = 7;
Foo z = "asdf";
assert(x < y); // comparing ints works correctly
assertThrown!AssertError(x < z); // cannot compare int and string
assert(max(x, y) == y); // D's max works
}
The Problem
While I can now use x.value.match!(...) where I used to use x.match!(...), I would like to still be able to call .match! directly on x, and also use match!(...)(x, y) instead of match!(...)(x.value, y.value). I do not like the idea of inserting hundreds of .value throughout my code just to make certain functions like max work, and would prefer if there were a more elegant solution. I tried tinkering around with defining a custom opDispatch using mixins but I couldn't get that to play nicely with the existing SumType:
struct Foo {
SumType!(int, string) value;
this(T)(T v) {
value = v;
}
ref Atom opAssign(T)(T rhs) {
value = rhs;
return this;
}
int opCmp(Foo other) {
return match!(
(a, b) => a < b ? -1 : a == b ? 0 : 1,
(_1, _2) => assert(0, "Cannot match")
)(value, other.value);
}
auto opDispatch(string name, T...)(T vals) {
return mixin("value." ~ name)(vals);
}
}
void main() {
Foo y = 7;
y.match!(
(int intValue) => writeln("Received an integer"),
(string strValue) => writeln("Received a string")
);
}
And I am unable to decode the error which results:
mwe.d(38): Error: none of the overloads of template `std.sumtype.match!(function (int intValue) #safe
{
writeln("Received an integer");
return ;
}
, function (string strValue) #safe
{
writeln("Received a string");
return ;
}
).match` are callable using argument types `!()(Foo)`
C:\D\dmd2\windows\bin\..\..\src\phobos\std\sumtype.d(1659): Candidate is: `match(SumTypes...)(auto ref SumTypes args)`
with `SumTypes = (Foo)`
must satisfy the following constraint:
` allSatisfy!(isSumType, SumTypes)`
Beyond that I am out of ideas as to how to find a less clunky solution.
I suggest giving alias this a try. Similar to class inheritance, this lets you specialize a type and let other things fall back to the original member.
import std.stdio : writeln;
import std.exception : assertThrown;
import std.algorithm.comparison : max;
import core.exception : AssertError;
import std.sumtype;
struct Foo {
SumType!(int, string) value;
this(T)(T v) {
value = v;
}
int opCmp(Foo other) {
return match!(
(a, b) => a < b ? -1 : a == b ? 0 : 1,
(_1, _2) => assert(0, "Cannot match")
)(value, other.value);
}
alias value this;
}
void main() {
Foo x = 3;
Foo y = 7;
Foo z = "asdf";
assert(x < y); // comparing ints works correctly
assertThrown!AssertError(x < z); // cannot compare int and string
assert(max(x, y) == y); // D's max works
// this will now automatically fall back to y.value.match
y.match!(
(int intValue) => writeln("Received an integer"),
(string strValue) => writeln("Received a string")
);
}
See, you still must construct your special type, but then after that, it will look up there for members. It will find the opCmp, letting it extend the type. But then for everything else, since it isn't there, it will try checking obj.value instead, falling back to the original type.
This doesn't always work, and it means it will implicitly convert too, meaning you can pass a Foo to a void thing(SumType!(int, string)) with it passing foo.value to the function, which may or may not be desirable.
But I think it is the closest thing to what you want here.
(note btw why you got an error originally is that match isn't actually a member of SumType. it is an outside free function that takes all the match lambdas as template arguments. An opDispatch could forward template arguments too - it can be done in a two-level definition - but since match is not a member anyway, it isn't quite going to solve things anyway whereas the alias this does seem to work)

While loop - how to remove code duplication

It's not the first time I find myself in the following situation:
bool a = some_very_long_computation;
bool b = another_very_long_computation;
while (a && b) {
...
a = some_very_long_computation;
b = another_very_long_computation;
}
I don't want to compute everything in while condition, since computations are long and I want to give them appropriate names.
I don't want to create helper functions, because computation uses many local variables, and passing them all will make the code much less readable (and it will be some_huge_call).
It's unknown whether loop body will be executed at least once.
What is a good pattern in such situation? Currently I face it in C++, but I've encountered this in other languages as well. I can solve it by using additional variable isFirstPass, but it looks ugly (and, I guess, will cause some warnings):
bool a, b;
bool isFirstPass = true;
do {
if (!isFirstPass) {
...
} else {
isFirstPass = false;
}
a = some_very_long_computation;
b = another_very_long_computation;
} while (a && b);
The direct simplification of your code is:
while (
some_very_long_computation &&
another_very_long_computation
) {
...
}
If you want to keep the variables a and b:
bool a, b;
while (
(a = some_very_long_computation) &&
(b = another_very_long_computation)
) {
...
}
If you don't want to put the conditions into the while condition:
while (true) {
bool a = some_very_long_computation;
bool b = another_very_long_computation;
if (!(a && b)) {
break;
}
...
}
You could also create helper lambdas (which have access to local variables):
auto fa = [&]() { return some_very_long_computation; };
auto fb = [&]() { return another_very_long_computation; };
while (fa() && fb()) {
...
}

Function returning a container containing specific elements of input container

I have a vector or list of which I only want to apply code to specific elements. E.g.
class Container : public std::vector<Element*>
Or
class Container : public std::list<Element*>
And:
Container newContainer = inputContainer.Get(IsSomething);
if (!newContainer.empty()) {
for (Element* const el: newContainer ) {
[some stuff]
}
} else {
for (Element* const el : inputContainer) {
[some stuff]
}
}
I've written a member function Get() as follows.
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output;
std::copy_if(cbegin(), cend(), std::inserter(output, output.end()), fn);
return output;
}
and IsSomething would be a lambda, e.g.
auto IsSomething= [](Element const* const el)->bool { return el->someBool; };
From performance perspective: Is this a good approach? Or would it be better to copy and remove?
template<typename Fn>
auto Container::Get(const Fn& fn) const {
Container output(*this);
output.erase(std::remove_if(output.begin(), output.end(), fn), end(output));
return output;
}
Or is there a better approach anyhow?
edit: different example
As my previous example can be written in a better way, let's show a different example:
while (!(container2 = container1.Get(IsSomething)).empty()&&TimesFooCalled<SomeValue)
{
Container container3(container2.Get(IsSomething));
if (!container3.empty()) {
Foo(*container3.BestElement());
} else {
Foo(*container2.BestElement());
}
}
Not answering your direct question, but note that you can implement the original algorithm without copying anything. Something like this:
bool found = false;
for (Element* const el: inputContainer) {
if (IsSomething(el)) {
found = true;
[some stuff]
}
}
if (!found) {
for (Element* const el : inputContainer) {
[some stuff]
}
}
The usual pattern that I use is something like this:
for(auto const * item : inputContainer) if(IsSomething(item)) {
// Do stuff with item
}
This is usually good enough, so other approaches seem overkill.
For better performance it is always better not to copy or remove elements from the list you get. In my experience it's even faster if you only go through the list once, for caching reasons. So here is what I would do to find one or the other "best" value from a list:
auto const isBetter = std::greater<Element>();
Element const * best = nullptr, const * alt_best = nullptr;
for(Element const * current : inputContainer) {
if(IsSomething(current)) {
if(!best || isBetter(*best, *current)) best = current;
} else {
if(!alt_best || isBetter(*alt_best, *current)) alt_best = current;
}
}
if(best) {
// do something with best
} else if(alt_best) {
// do something with alt_best
} else {
// empty list
}
If you find yourself doing this a lot or you want to make this part of your class's interface you could consider writing an iterator that skips elements you don't like.
If you actually want to remove the item from the list, you could do something like this:
inputContainer.erase(std::remove_if(std::begin(inputContainer), std::end(inputContainer),
[](Element const *item) {
if(IsSomething(item)) {
// Do something with item
return true;
}
return false;
}
));

branching based on two boolean variables

Suppose I have two boolean variables, and I want to do completely different things based on their values. What is the cleanest way to achieve this?
Variant 1:
if (a && b)
{
// ...
}
else if (a && !b)
{
// ...
}
else if (!a && b)
{
// ...
}
else
{
// ...
}
Variant 2:
if (a)
{
if (b)
{
// ...
}
else
{
// ...
}
}
else
{
if (b)
{
// ...
}
else
{
// ...
}
}
Variant 3:
switch (a << 1 | b)
{
case 0:
// ...
break;
case 1:
// ...
break;
case 2:
// ...
break;
case 3:
// ...
break;
}
Variant 4:
lut[a][b]();
void (*lut[2][2])() = {false_false, false_true, true_false, true_true};
void false_false()
{
// ...
}
void false_true()
{
// ...
}
void true_false()
{
// ...
}
void true_true()
{
// ...
}
Are variants 3 and 4 too tricky/complicated for the average programmer? Any other variants I have missed?
The first variant is the clearest and most readable, but it can be adjusted:
if (a && b) {
// ...
} else if (a) { // no need to test !b here - b==true would be the first case
// ...
} else if (b) { //no need to test !a here - that would be the first case
// ...
} else { // !a&&!b - the last remaining
// ...
}
You forgot about:
if (a) a_true(b);
else a_false(b);
which is probably the best choice when appliable, and when you truly need 4 different behaviours.
If you have more than 2 bools, I take this as a code smell if I have 2^n different behaviours which don't factorize well like the above. Then I may think about doing:
enum { case1, case2, ... }
int dispatch_cases(bool a, bool b, bool c, ..., bool z);
switch (dispatch_cases(a, b, ..., z))
{
case case1:
...
};
but without context, it is hard to tell whether such complexity is necessary.
IMHO, I will go for variant 3. Because personally, I don't like if/else when I am checking for equality. It clearly states that there are only 4 possibilities.
One minor edit would be:
inline int STATES(int X, int Y) { return (X<<1) | Y; }
// ...
switch (STATES(a,b))
To make it more fancy, you may replace 0,1,2,3 with an enum as well.
enum States {
NONE,
ONLY_B.
ONLY_A,
BOTH
};
For just two booleans, any of them is good and reasonable. One can choose based on his taste.
However, if there are more than two booleans, say four booleans, then I personally would go with lookup table, and I would do this as:
typedef void (*functype)();
//16 functions to handle 16 cases!
void f0() {}
void f1() {}
//...so on
void f15() {}
//setup lookup table
functype lut[] =
{
f0, //0000 - means all bool are false
f1, //0001
f2, //0010
f3, //0011
f4, //0100
f5, //0101
f6, //0110
f7, //0111
f8, //1000
f9, //1001
f10, //1010
f11, //1011
f12, //1100
f13, //1101
f14, //1110
f15 //1111 - means all bool are true
};
lut[MakeInt(b1,b2,b3,b4)](); //call
MakeInt() is easy to write:
int MakeInt(bool b1, bool b2, bool b3, bool b4)
{
return b1 | (b2<<1) | (b3 <<2) | (b4<<3);
}