How to refactor this while loop to get rid of "continue"? - c++

I have a while (!Queue.empty()) loop that processes a queue of elements. There are a series of pattern matchers going from highest-priority to lowest-priority order. When a pattern is matched, the corresponding element is removed from the queue, and matching is restarted from the top (so that the highest-priority matchers get a chance to act first).
So right now it looks something like this (a simplified version):
while (!Queue.empty())
{
auto & Element = *Queue.begin();
if (MatchesPatternA(Element)) { // Highest priority, since it's first
// Act on it
// Remove Element from queue
continue;
}
if (MatchesPatternB(Element)) {
// Act on it
// Remove Element from queue
continue;
}
if (MatchesPatternC(Element)) { // Lowest priority, since it's last
// Act on it
// Remove Element from queue
continue;
}
// If we got this far, that means no pattern was matched, so
// Remove Element from queue
}
This works, but I want to refactor this loop in some way to remove the use of the keyword continue.
Why? Because if I want to outsource a pattern matching to an external function, it obviously breaks. E.g.
void ExternalMatching(...)
{
if (MatchesPatternB(Element)) {
// Act on it
// Remove Element from queue
continue; // This won't work here
}
}
while (!Queue.empty())
{
auto & Element = *Queue.begin();
if (MatchesPatternA(Element)) {
// Act on it
// Remove Element from queue
continue;
}
ExternalMatching(...);
if (MatchesPatternC(Element)) {
// Act on it
// Remove Element from queue
continue;
}
// If we got this far, that means no pattern was matched, so
// Remove Element from queue
}
I don't want to have to write repetitive if statements like if (ExternalMatching(...)) { ... continue; }, I'd rather find a cleaner way to express this logic.
This simplified example might make it seem like a good idea to make pattern matching more general rather than having distinct MatchesPatternA, MatchesPatternB, MatchesPatternC, etc. functions. But in my situation the patterns are quite complicated, and I'm not quite ready to generalize them yet. So I want to keep that part as is, separate functions.
Any elegant ideas? Thank you!

If you have access to C++11 I would like to suggest another solution. Basicaly I created a container of handlers and actions that can be adjusted in runtime. It may be a pro or con for your design depending on your requirements. Here it is:
#include <functional>
typedef std::pair<std::function<bool(const ElementType &)>,
std::function<void(ElementType &)> > HandlerData;
typedef std::vector<HandlerData> HandlerList;
HandlerList get_handlers()
{
HandlerList handlers;
handlers.emplace_back([](const ElementType &el){ return MatchesPatternA(el); },
[](ElementType &el){ /* Action */ });
handlers.emplace_back([](const ElementType &el){ return MatchesPatternB(el); },
[](ElementType &el){ /* Action */ });
handlers.emplace_back([](const ElementType &el){ return MatchesPatternC(el); },
[](ElementType &el){ /* Action */ });
return handlers;
}
int main()
{
auto handlers = get_handlers();
while(!Queue.empty()) {
auto &Element = *Queue.begin();
for(auto &h : handlers) {
// check if handler matches the element
if(h.first(Element)) {
// act on element
h.second(Element);
break;
}
}
// remove element
Queue.pop_front();
}
}

I would recommend using a function that does the pattern matching (but does not act on the result) and then a set of functions that act on the different options:
enum EventType {
A, B, C //, D, ...
};
while (!queue.empty()) {
auto & event = queue.front();
EventType e = eventType(event); // Internally does MatchesPattern*
// and returns the match
switch (e) {
case A:
processA(event);
break;
case B:
processB(event);
This way you clearly separate the matching from the processing, the loop is just a simple dispatcher

Consider an interface:
class IMatchPattern
{
public:
virtual bool MatchesPattern(const Element& e) = 0;
};
Then you can organize a container of objects implementing IMatchPattern, to allow for iterative access to each pattern match method.

You can change your ExternalMatching to return bool, indicating that the processing has been done. This way the caller would be able to continue evaluating if necessary:
bool ExternalMatching(...)
{
if (MatchesPatternB(Element) {
// Act on it
// Remove Element from queue
return true;
}
return false;
}
Now you can call it like this:
if (ExternalMatchin1(...)) continue;
if (ExternalMatchin2(...)) continue;
...
if (ExternalMatchingN(...)) continue;

Ok, I ended up rewriting the loop more akin to this.
Huge thanks and credit goes to Yuushi, dasblinkenlight, David Rodríguez for their help; this answer is based on a combination of their answers.
bool ExternalMatching(...)
{
bool Match;
if ((Match = MatchesPatternX(Element))) {
// Act on it
} else if ((Match = MatchesPatternY(Element))) {
// Act on it
}
return Match;
}
while (!Queue.empty())
{
auto & Element = Queue.front();
if (MatchesPatternA(Element)) { // Highest priority, since it's first
// Act on it
} else if (MatchesPatternB(Element)) {
// Act on it
} else if (ExternalMatching(...)) {
} else if (MatchesPatternC(Element)) { // Lowest priority, since it's last
// Act on it
}
// Remove Element from queue
}
Now, I know there's further room for improvement, see answers of Mateusz Pusz and Michael Sh. However, this is good enough to answer my original question, and it'll do for now. I'll consider improving it in the future.
If you're curious to see the real code (non-simplified version), see here:
https://github.com/shurcooL/Conception/blob/38f731ccc199d5391f46d8fce3cf9a9092f38c65/src/App.cpp#L592
Thanks everyone again!

I would like to suggest a Factory function that would take the Element and create an appropriate handler and return the interface pointer to the handler.
while (!Queue.empty())
{
auto & Element = *Queue.begin();
// get the appropriate handler object pointer e.g.
IPatternHandler *handler = Factory.GetHandler(Element);
handler->handle();
// clean up handler appropriately
}

Related

std::list and garbage Collection algorithm

I have a server that puts 2 players together on request and starts a game Game in a new thread.
struct GInfo {Game* game; std::thread* g_thread};
while (true) {
players_pair = matchPlayers();
Game* game = new Game(players_pair);
std::thread* game_T = new std::thread(&Game::start, game);
GInfo ginfo = {game, game_T}
_actives.push_back(ginfo); // std::list
}
I am writing a "Garbage Collector", that runs in another thread, to clean the memory from terminated games.
void garbageCollector() {
while (true) {
for (std::list<Ginfo>::iterator it = _actives.begin(); it != _actives.end(); ++it) {
if (! it->game->isActive()) {
delete it->game; it->game = nullptr;
it->g_thread->join();
delete it->g_thread; it->g_thread = nullptr;
_actives.erase(it);
}
}
sleep(2);
}
}
This generates a segfault, I suspect it is because of the _active.erase(it) being in the iteration loop.
For troubleshooting, I made _actives an std::vector (instead of std::list) and applied the same algorithm but using indexes instead of iterators, it works fine.
Is there a way around this?
Is the algorithm, data structure used fine? Any better way to do the garbage collection?
Help is appreciated!
If you have a look at the documentation for the erase method it returns an iterator to the element after the one that was removed.
The way to use that is to assign the returned value to your iterator like so.
for (std::list<Ginfo>::iterator it = _actives.begin(); it != _actives.end();) {
if (! it->game->isActive()) {
delete it->game; it->game = nullptr;
it->g_thread->join();
delete it->g_thread; it->g_thread = nullptr;
it = _actives.erase(it);
}
else {
++it;
}
}
Since picking up the return value from erase advances the iterator to the next element, we have to make sure not to increment the iterator when that happens.
On an unrelated note, variable names starting with underscore is generally reserved for the internals of the compiler and should be avoided in your own code.
Any better way to do the garbage collection?
Yes, don't use new,delete or dynamic memory alltogether:
struct Players{};
struct Game{
Game(Players&& players){}
};
struct GInfo {
GInfo(Players&& players_pair):
game(std::move(players_pair)),g_thread(&Game::start, game){}
Game game;
std::thread g_thread;
};
std::list<GInfo> _actives;
void someLoop()
{
while (true) {
GInfo& ginfo = _actives.emplace_back(matchPlayers());
}
}
void garbageCollector() {
while (true) {
//Since C++20
//_active.remove_if([](GInfo& i){ return !i.game.isActive();});
//Until C++20
auto IT =std::remove_if(_actives.begin(),_actives.end(),
[](GInfo& i){ return !i.game.isActive();});
_active.erase(IT,_active.end());
//
sleep(2);
}
}
There might be a few typos, but that's the idea.

is there a better way to make this software flow

I have several functions that try and evaluate some data. Each function returns a 1 if it can successfully evaluate the data or 0 if it can not. The functions are called one after the other but execution should stop if one returns a value of 1.
Example functions look like so:
int function1(std::string &data)
{
// do something
if (success)
{
return 1;
}
return 0;
}
int function2(std::string &data)
{
// do something
if (success)
{
return 1;
}
return 0;
}
... more functions ...
How would be the clearest way to organise this flow? I know I can use if statements as such:
void doSomething(void)
{
if (function1(data))
{
return;
}
if (function2(data))
{
return;
}
... more if's ...
}
But this seems long winded and has a huge number of if's that need typing. Another choice I thought of is to call the next function from the return 0 of the function like so
int function1(std::string &data)
{
// do something
if (success)
{
return 1;
}
return function2(data);
}
int function2(std::string &data)
{
// do something
if (success)
{
return 1;
}
return function3(data);
}
... more functions ...
Making calling cleaner because you only need to call function1() to evaluate as far as you need to but seems to make the code harder to maintain. If another check need to be inserted into the middle of the flow, or the order of the calls changes, then all of the functions after the new one will need to be changed to account for it.
Am I missing some smart clear c++ way of achieving this kind of program flow or is one of these methods best. I am leaning towards the if method at the moment but I feel like I am missing something.
void doSomething() {
function1(data) || function2(data) /* || ... more function calls ... */;
}
Logical-or || operator happens to have the properties you need - evaluated left to right and stops as soon as one operand is true.
I think you can make a vector of lambdas where each lambdas contains specific process on how you evaluate your data. Something like this.
std::vector<std::function<bool(std::string&)> listCheckers;
listCheckers.push_back([](std::string& p_data) -> bool { return function1(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function2(p_data); });
listCheckers.push_back([](std::string& p_data) -> bool { return function3(p_data); });
//...and so on...
//-----------------------------
std::string theData = "Hello I'm a Data";
//evaluate all data
bool bSuccess = false;
for(fnChecker : listCheckers){
if(fnChecker(theData)) {
bSuccess = true;
break;
}
}
if(bSuccess ) { cout << "A function has evaluated the data successfully." << endl; }
You can modify the list however you like at runtime by: external objects, config settings from file, etc...

GOF Composite Design Pattern CompositeObject::Remove Recursive Implementation in C++

This is the part of question from my question asked in codereview website:
GOF Composite Design Pattern Implementation Using Modern C++
The post has complete information/implementation about it but here I am posting this question to understand about the following information:
How to implement CompositeEquipment::Remove?.
Based on my understanding, it should do recursive search in all composite object in which client has invoked and recursively all its child objects which can also be of composite type. Just to illustrate from above implementation, if client write the as cabinet->Remove(bus); it would not remove bus object as it is the child of chassis object. This seems to be incorrect to me. However I am not able to implement the CompositeEquipment::Remove in such a way that it searches recursively if child objects themselves are of composite.
So far I have came of with the following implementation which just searches the composite objects which client has involved for Remove method.
//To find out whether items are in the composite objects
class Name_Equal {
private:
Equipment::EquipmentSmartPtr val;
public:
Name_Equal(const Equipment::EquipmentSmartPtr& v) :val(v) { }
bool operator()(const Equipment::EquipmentSmartPtr& x) const {
return (x->Name() == val->Name());
}
};
void CompositeEquipment::Remove(EquipmentSmartPtr entry) {
find_equipment(_equipment, entry);
}
void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
}
}
Kindly let me know in case any additional information or complete code needs to post here as well.
There are two options:
Provide a virtual function Remove in the base class and make it a noop implementation. Then add a few more lines to CompositeEquipment::find_equipment.
void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
sptr->Remove(entry);
}
}
}
Use dynamic_cast to determine whether an item of the composite is a composite also. If so, call Remove on it. I prefer this option.
void CompositeEquipment::find_equipment(std::vector<EquipmentSmartPtr>& vec,
EquipmentSmartPtr& entry){
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
Equipment* ptr = dynamic_cast<Equipment*>(sptr.get());
if ( ptr )
{
ptr->Remove(entry);
}
}
}
}
A bit about names... find_equipment seems a strange name for the function. I would put the whole thing in Remove.
void CompositeEquipment::Remove(EquipmentSmartPtr& entry){
std::vector<EquipmentSmartPtr>& vec = _equipment;
Name_Equal eq(entry);
auto itrpos = std::find_if(std::begin(vec), std::end(vec), eq);
if (itrpos != std::end(vec)) {
vec.erase(itrpos);
} else {
for ( EquipmentSmartPtr sptr : vec )
{
Equipment* ptr = dynamic_cast<Equipment*>(sptr.get());
if ( ptr )
{
ptr->Remove(entry);
}
}
}
}

How to store the state of a deeply-nested loop?

I am trying to refactor the following code, as I don't think it is structured well.
Can you think of a more elegant way to do this?
Bar::Bar()
{
m_iter1 = 0;
m_iter2 = 0;
}
bool Bar::foo()
{
_reinitialize();
for (; m_iter1 < 2; m_iter1++, m_iter2 = 0) {
_log("TRYING METHOD: [%d]", m_iter1);
if (_something_wrong(m_iter1)) {
return false;
}
for (; m_iter2 < 6; m_iter2++) {
if (_try_with_these_params(m_iter1, m_iter2, ...)) {
m_status = success;
// store next iteration in case we need to retry.
m_iter2++;
return true;
}
}
}
return false;
}
bool try_foo(Bar& bar)
{
if (bar.foo()) {
if (meet_some_criteria) {
return true;
} else {
bar.invalidate();
// retry. the Bar object stores the state.
try_foo(bar);
}
} else {
return false;
}
}
int main()
{
Bar bar;
if (try_foo(bar)) {
_log("SUCCESS");
} else {
_log("FAILURE");
}
}
The code loops over different parameter sets and tries to perform some action with these parameters. If the action is successful, then external code may invalidate the action and attempt to retry. The object which performs the action stores the state, so that external code may retry and re-enter the parameter loop at the place it left off.
The output using one parameters affect others, so the calculations need to be accomplished locally within the Bar class.
I would like to extend this idea to more dimensions, but doing so with the current design is clumsy.
A lot here depends on how expensive the various actions are.
If initially generating a candidate parameter set is cheap (and the set isn't too large), then you might want to just generate all the candidate sets, then give that result to the external code and try each in turn until you find one that the external code will accept.

How can I find the depth of a recursive function in C++

How can I find the current depth inside a recursive function in C++ without passing in the previous level? i.e. is it possible to know how many times the function was called without using a parameter to keep track of the level and passing that number in as a parameter each time the function is called?
For example my recursive function looks like this:
DoSomething(int level)
{
print level;
if (level > 10)
return;
DoSomething(++level);
}
main
{
DoSomething(0);
}
Building on the answer already given by JoshD:
void recursive()
{
static int calls = 0;
static int max_calls = 0;
calls++;
if (calls > max_calls)
max_calls = calls;
recursive();
calls--;
}
This resets the counter after the recursive function is complete, but still tracks the maximum depth of the recursion.
I wouldn't use static variables like this for anything but a quick test, to be deleted soon after. If you really need to track this on an ongoing basis there are better methods.
You could use a static variable in the function...
void recursive()
{
static int calls = 0;
calls++;
recursive();
}
Of course, this will keep counting when you start a new originating call....
If you want it to be re-entrant and thread-safe, why not:
void rec(int &level) // reference to your level var
{
// do work
rec(++level); // go down one level
}
main()
{
//and you call it like
int level=0;
rec(level);
cout<<level<<" levels."<<endl;
}
No static/global variables to mess up threading and you can use different variables for different recursive chains for re-entrancy issues.
You can use a local static variable, if you don't care about thread-safety.
Although, this will only give you a proper count the first time you run your recursive routine. A better technique would be a RAII guard-type class which contains an internal static variable. At the start of the recursive routine, construct the guard class. The constructor would increment the internal static variable, and the destructor would decrement it. This way, when you create a new stack-frame the counter increments by one, and when you return from each stack-frame the counter would decrement by one.
struct recursion_guard
{
recursion_guard() { ++counter; }
~recursion_guard() { --counter; }
static int counter;
};
int recursion_guard::counter = 0;
void recurse(int x)
{
recursion_guard rg;
if (x > 10) return;
recurse(x + 1);
}
int main()
{
recurse(0);
recurse(0);
}
Note however, that this is still not thread-safe. If you need thread-safety, you can replace the static-storage variable with a thread-local-storage variable, either using boost::thread_specific_ptr or the C++0x thread local facilities.
You could also pass in the level as a template parameter, if it can be determined at compile-time. You could also use a function object. This is by far and away the best option - less hassle, and static variables should be avoided wherever possible.
struct DoSomething {
DoSomething() {
calls = 0;
}
void operator()() {
std::cout << calls;
calls++;
if (calls < 10)
return operator()();
return;
}
int calls;
};
int main() {
DoSomething()(); // note the double ().
std::cin.get();
}
convert level to an instance variable of a new object (typically a template) capable of containing the arguments and (possibly) the function. then you can reuse the recursion accumulator interface.
You can also try using a global variable to log the depth.
var depth = 0;
DoSomething()
{
print ++depth;
if (depth > 10)
return;
DoSomething();
}
main
{
DoSomething(0);
}
I came here when I sensed that some recursion is required, because I was implementing a function that can validate the chain of trust in a certificate chain. This is not X.509 but instead it is just the basics wherein the issuer key of a certificate must match the public key of the signer.
bool verify_chain(std::vector<Cert>& chain,
Cert* certificate,
unsigned char* pOrigin = nullptr, int depth = 0)
{
bool flag = false;
if (certificate == nullptr) {
// use first element in case parameter is null
certificate = &chain[0];
}
if (pOrigin == nullptr) {
pOrigin = certificate->pubkey;
} else {
if (std::memcmp(pOrigin, certificate->pubkey, 32) == 0) {
return false; // detected circular chain
}
}
if (certificate->hasValidSignature()) {
if (!certificate->isRootCA()) {
Cert* issuerCert = certificate->getIssuer(chain);
if (issuerCert) {
flag = verify_chain(chain, issuerCert, pOrigin, depth+1);
}
} else {
flag = true;
}
}
if (pOrigin && depth == 1) {
pOrigin = nullptr;
}
return flag;
}
I needed to know the recursion depth so that I can correctly clean up pOrigin. at the right stack frame during the unwinding of the call stack.
I used pOrigin to detect a circular chain, without which the recursive call can go on forever. For example,
cert0 signs cert1
cert1 signs cert2
cert2 signs cert0
I later realized that a simple for-loop can do it for simple cases when there is only one common chain.
bool verify_chain2(std::vector<Cert> &chain, Cert& cert)
{
Cert *pCert = &cert;
unsigned char *startkey = cert.pubkey;
while (pCert != nullptr) {
if (pCert->hasValidSignature()) {
if (!pCert->isRootCA()) {
pCert = pCert->getIssuer(chain);
if (pCert == nullptr
|| std::memcmp(pCert->pubkey, startkey, 32) == 0) {
return false;
}
continue;
} else {
return true;
}
} else {
return false;
}
}
return false;
}
But recursion is a must when there is not one common chain but instead the chain is within each certificate. I welcome any comments. Thank you.