I have mocked a function which takes std::set (stl) as an argument and I expected it to be called with the right args. std::set is a set of user-defined struct and I just want to verify one field of that struct to have one value for all the member of the set.
ie
struct my_struct {
int i;
int j;
int k;
}
using my_set = std::set<my_struct>;
MOCK_METHOD(void, my_func, (my_set));
EXPECT_CALL(obj, my_func(_))
.Times(1);
Now I want to expect my_func to be called with my_set and each member of my_set is my_struct and my_struct.i should be 1 for all the members.
I understand it could be done with Matcher and Each but now sure how to do that as I run into compilation error
The key is to use ::testing::Each matcher with ::testing::Field matcher combined. Each iterates over all elements of the container argument and Field matcher allows you to set proper expectations on the user-defined struct fields. Complete example:
struct my_struct {
int i;
int j;
int k;
};
auto my_set_comp = [](const auto& l, const auto& r) { return std::tie(l.i, l.j, l.k) < std::tie(r.i, r.j, r.k); };
using my_set = std::set<my_struct, decltype(my_set_comp)>;
class MockClass {
public:
MOCK_METHOD(void, my_func, (my_set));
};
TEST(SetTest, test1) {
MockClass obj{};
my_set a_set{my_set_comp};
a_set.emplace(my_struct{1, 1, 1});
a_set.emplace(my_struct{1, 2, 2});
a_set.emplace(my_struct{1, 3, 3});
EXPECT_CALL(obj, my_func(::testing::Each(::testing::Field(&my_struct::i, 1)))).Times(1);
obj.my_func(a_set);
}
or here.
Related
I am new to OOP in C++. I got a doubt. I know it may be a silly doubt.
In the code below in main function, commented line will give error as I can not access private data memebers directly. but in the member function complex add(complex &C) I created a object temp of class complex. How can I access the data member of object temp directly and modify them as those are private. Like in the main function, should it not throw error? Is there any rule that in the member function of class we can access private data of a object of same class directly.
using namespace std;
class complex{
private:
int real;
int img;
public:
complex(int r = 0, int i = 0);
complex add(complex &C);
};
complex :: complex(int r, int i){
real = r;
img = i;
}
complex complex :: add(complex &C){
complex temp;
temp.real = real + C.real;
temp.img = img + C.img;
return temp;
}
int main() {
complex c1(3,4);
complex c2(5,7);
complex c3;
// c3.real = 3;
// c3.img = 5;
c3 = c1.add(c2);
return 0;
}
I try and stick to rule, keep your member variables private, if you need to change them or access them once the object is created, use a public get / set function.
e.g:
int complex::GetReal() const { return m_real; }
void complex::SetReal(const int i) { m_real = i; }
What is the importance of defining indegree vector in the private of a class? It could have been defined in alltopologicalSort() function.
class Graph
{
int V; // No. of vertices
// Pointer to an array containing adjacency list
list<int> *adj;
// Vector to store indegree of vertices
vector<int> indegree;
// A function used by alltopologicalSort
void alltopologicalSortUtil(vector<int>& res,
bool visited[]);
public:
Graph(int V); // Constructor
// function to add an edge to graph
void addEdge(int v, int w);
// Prints all Topological Sorts
void alltopologicalSort();
};
And how it is functioning in below addedge function
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v's list.
// increasing inner degree of w by 1
indegree[w]++;
}
Use of indegree, please explain here the role of addEdge function in decrementing indegree
void Graph::alltopologicalSortUtil(vector<int>& res,
bool visited[])
{
// To indicate whether all topological are found
// or not
bool flag = false;
for (int i = 0; i < V; i++)
{
// If indegree is 0 and not yet visited then
// only choose that vertex
if (indegree[i] == 0 && !visited[i])
{
// reducing indegree of adjacent vertices
list<int>:: iterator j;
for (j = adj[i].begin(); j != adj[i].end(); j++)
indegree[*j]--;
// including in result
res.push_back(i);
visited[i] = true;
alltopologicalSortUtil(res, visited);
// resetting visited, res and indegree for
// backtracking
visited[i] = false;
res.erase(res.end() - 1);
for (j = adj[i].begin(); j != adj[i].end(); j++)
indegree[*j]++;
flag = true;
}
}
}
This is the link to complete code of finding All Topological Sorts of Directed Acyclic Graph
https://www.geeksforgeeks.org/all-topological-sorts-of-a-directed-acyclic-graph/
I have got my answer from above discussion with Gupta and kaya3
Indegree could have been defined in some function and then passed to alltopologicalSort() function as a reference. But then defining it in class makes it easier to deal with.
And Data members of a class are always kept private because of encapsulation rules
I have a multi index with 2 indexes(in real code, they are of different type).
class CrUsersKeys{
int IMSI;
int TIMESTAMP;
}
After i find an entry in the multi index, I have the iterator of the entry.
auto it = multi.GetIteratorBy<IMSI_tag>(searchKey);
Now i want to loop through all the indexed members in this specific (*it) and check them. Note that i don't want to iterate through the iterator, but through the the indexed element of CrUsersKeys. How can i do it?
for(key in it)
{
if(isGoodKey(key))
std::cout<<"key "<<key <<" is good key"<<std::endl;
}
So it should check isGoodKey((*it).IMSI) and isGoodKey((*it).TIMESTAMP).
CrUsersKeys is template parameter, so i can't really know the members of CrUsersKeys.
Code example at http://coliru.stacked-crooked.com/a/d97195a6e4bb7ad4
My multi index class is in shared memory.
Your question has little to do with Boost.MultiIndex and basically asks for a way to compile-time iterate over the members of a class. If you're OK with CrUsersKeys being defined as a std::tuple (or a tuple-like class), then you can do something like this (C++17):
Edit: Showed how to adapt a non-tuple class to the framework.
Live On Coliru
#include <tuple>
template<typename Tuple,typename F>
bool all_of_tuple(const Tuple& t,F f)
{
const auto fold=[&](const auto&... x){return (...&&f(x));};
return std::apply(fold,t);
}
#include <iostream>
#include <type_traits>
bool isGoodKey(int x){return x>0;}
bool isGoodKey(const char* x){return x&&x[0]!='\0';}
template<typename Tuple>
bool areAllGoodKeys(const Tuple& t)
{
return all_of_tuple(t,[](const auto& x){return isGoodKey(x);});
}
struct CrUsersKeys
{
int IMSI;
const char* TIMESTAMP;
};
bool areAllGoodKeys(const CrUsersKeys& x)
{
return areAllGoodKeys(std::forward_as_tuple(x.IMSI,x.TIMESTAMP));
}
int main()
{
std::cout<<areAllGoodKeys(std::make_tuple(1,1))<<"\n"; // 1
std::cout<<areAllGoodKeys(std::make_tuple(1,"hello"))<<"\n"; // 1
std::cout<<areAllGoodKeys(std::make_tuple(1,0))<<"\n"; // 0
std::cout<<areAllGoodKeys(std::make_tuple("",1))<<"\n"; // 0
std::cout<<areAllGoodKeys(CrUsersKeys{1,"hello"})<<"\n"; // 1
std::cout<<areAllGoodKeys(CrUsersKeys{0,"hello"})<<"\n"; // 0
std::cout<<areAllGoodKeys(CrUsersKeys{1,""})<<"\n"; // 0
}
class abc
{
};
int main()
{
std::map<abc, int> m;
abc ob, ob1;
m.insert(std::make_pair(ob, 1));
m.insert(std::make_pair(ob1, 2));
}
Error coming is:
/usr/lib/gcc/i686-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_function.h:237:22: note: ‘const abc’ is not derived from ‘const std::multimap<_Key, _Tp, _Compare, _Alloc>’
Does any addition function need be added in class so that it can be made hashable?
Got it. Since std::map sorts when entering a new key in map, so if key is a class object, we must overload class's "<" operator, then it would work fine.
class abc
{
public:
bool operator< (const abc& userObj) const
{
return true;
}
};
int main()
{
std::map<abc, int> m;
abc ob;
abc ob1;
m.insert(std::make_pair(ob, 1));
m.insert(std::make_pair(ob1, 2));
}
What does one do to make something like this work?
void (^)(void) *someBlock = ^{
//some code
};
Dmitry's answer is exactly right. Think of the block syntax as a C function declaration:
// C function -> <return type> <function name> (<arguments>)
void someFunction(void)
{
// do something
}
// block -> <return type> (^<block variable name>) (<arguments>)
void (^someBlock)(void) = ^{
// do something
};
Another example:
// C function
int sum (int a, int b)
{
return a + b;
}
// block
int (^sum)(int, int) = ^(int a, int b) {
return a + b;
};
So just think of the block syntax as a C function declaration:
First the return type int, then the name of the block variable (^sum) and then the list of arguments types (int, int).
If, however, you need a certain type of block frequently in your app, use a typedef:
typedef int (^MySumBlock)(int, int);
Now you can create variables of the MySumBlock type:
MySumBlock debugSumBlock = ^(int a, int b) {
NSLog(#"Adding %i and %i", a, b);
return a + b;
};
MySumBlock normalSumBlock = ^(int a, int b) {
return a + b;
};
Hope that helps :)
Just block syntax
void (^someBlock)(void) = ^{
//some code
};