How can I get which part of an if expression is true? - c++

Assume I have code like:
if(condition1 || condition2 || condition 3 || condition4)
{
// this inner part will be executed if one of the conditions is true.
// Now I want to know by which condition this part is executed.
}

I'm sure there are better ways to do this, here's one:
int i = 0;
auto check = [&i](bool b)->bool
{
if (!b) ++i;
return b;
};
if (check(false) || // 0
check(false) || // 1
check(true) || // 2
check(false)) // 3
{
std::cout << i; // prints 2
}

|| is short circuit evaluation, so you can have code like this :
if(condition1 || condition2 || condition 3 || condition4)
{
if (condition1 )
{
//it must be condition1 which make the overall result true
}
else if (condition2)
{
//it must be condition2 which make the overall result true
}
else if (condition3)
{
//it must be condition3 which make the overall result true
}
else
{
//it must be condition4 which make the overall result true
}
// this inner part will executed if one of the condition true. Now I want to know by which condition this part is executed.
}
else
{
}

If the conditions are independent of each other, you need to check them separately, or, if they belong to one variable, you can use a switch statement
bool c1;
bool c2
if ( c1 || c2 )
{
// these need to be checked separately
}
int i; // i should be checked for multiple conditions. Here switch is most appropriate
switch (i)
{
case 0: // stuff
break;
case 1: // other stuff
break;
default: // default stuff if none of the conditions above is true
}

Without a switch you can use only or and if statements:
if(condition1 || condition2 || condition 3 || condition4) {
// this inner part will executed if one of the condition true.
//Now I want to know by which condition this part is executed.
if ( condition1 || condition2 ) {
if ( condition1 )
printf("Loop caused by 1");
else
printf("Loop caused by 2");
else
if ( condition3)
printf("Loop caused by 3");
else
printf("Loop caused by 4");
}
I'm not sure that this is the most efficient thing you've ever seen, but it will identify which of the four conditions caused entry into the if ... block.

If you need to know for programmatic reasons, i.e. run different code depending on which condition is true, you could do something like this
if (condition1)
{
...
}
else if (condition2)
{
...
}
else if (condition3)
{
...
}
else if (condition4)
{
...
}
else
{
...
}
If you only want to know for debugging reasons, just do a printout.

What about the comma operator?
By using that logical operators follow the short circuit evaluation method, the following works fine:
int w = 0; /* w <= 0 will mean "no one is true" */
if ( (w++, cond1) || (w++, cond2) || ... || (w++, condN) )
printf("The first condition that was true has number: %d.\n", w);

Related

How to improve logic to check whether 4 boolean values match some cases

I have four bool values:
bool bValue1;
bool bValue2;
bool bValue3;
bool bValue4;
The acceptable values are:
Scenario 1 | Scenario 2 | Scenario 3
bValue1: true | true | true
bValue2: true | true | false
bValue3: true | true | false
bValue4: true | false | false
So, for example, this scenario is not acceptable:
bValue1: false
bValue2: true
bValue3: true
bValue4: true
At the moment I have come up with this if statement to detect bad scenarios:
if(((bValue4 && (!bValue3 || !bValue2 || !bValue1)) ||
((bValue3 && (!bValue2 || !bValue1)) ||
(bValue2 && !bValue1) ||
(!bValue1 && !bValue2 && !bValue3 && !bValue4))
{
// There is some error
}
Can that statement logic be improved/simplified?
I would aim for readability: you have just 3 scenario, deal with them with 3 separate ifs:
bool valid = false;
if (bValue1 && bValue2 && bValue3 && bValue4)
valid = true; //scenario 1
else if (bValue1 && bValue2 && bValue3 && !bValue4)
valid = true; //scenario 2
else if (bValue1 && !bValue2 && !bValue3 && !bValue4)
valid = true; //scenario 3
Easy to read and debug, IMHO. Also, you can assign a variable whichScenario while proceeding with the if.
With just 3 scenarios, I would not go with something such "if the first 3 values are true I can avoid check the forth value": it's going to make your code harder to read and maintain.
Not an elegant solution maybe surely, but in this case is ok: easy and readable.
If your logic gets more complicated, throw away that code and consider using something more to store different available scenarios (as Zladeck is suggesting).
I really love the first suggestion given in this answer: easy to read, not error prone, maintainable
(Almost) off topic:
I don't write lot of answers here at StackOverflow. It's really funny that the above accepted answer is by far the most appreciated answer in my history (never had more than 5-10 upvotes before I think) while actually is not what I usually think is the "right" way to do it.
But simplicity is often "the right way to do it", many people seems to think this and I should think it more than I do :)
I would aim for simplicity and readability.
bool scenario1 = bValue1 && bValue2 && bValue3 && bValue4;
bool scenario2 = bValue1 && bValue2 && bValue3 && !bValue4;
bool scenario3 = bValue1 && !bValue2 && !bValue3 && !bValue4;
if (scenario1 || scenario2 || scenario3) {
// Do whatever.
}
Make sure to replace the names of the scenarios as well as the names of the flags with something descriptive. If it makes sense for your specific problem, you could consider this alternative:
bool scenario1or2 = bValue1 && bValue2 && bValue3;
bool scenario3 = bValue1 && !bValue2 && !bValue3 && !bValue4;
if (scenario1or2 || scenario3) {
// Do whatever.
}
What's important here is not predicate logic. It's describing your domain and clearly expressing your intent. The key here is to give all inputs and intermediary variables good names. If you can't find good variable names, it may be a sign that you are describing the problem in the wrong way.
We can use a Karnaugh map and reduce your scenarios to a logical equation.
I have used the Online Karnaugh map solver with circuit for 4 variables.
This yields:
Changing A, B, C, D to bValue1, bValue2, bValue3, bValue4, this is nothing but:
bValue1 && bValue2 && bValue3 || bValue1 && !bValue2 && !bValue3 && !bValue4
So your if statement becomes:
if(!(bValue1 && bValue2 && bValue3 || bValue1 && !bValue2 && !bValue3 && !bValue4))
{
// There is some error
}
Karnaugh Maps are particularly useful when you have many variables and many conditions which should evaluate true.
After reducing the true scenarios to a logical equation, adding relevant comments indicating the true scenarios is good practice.
The real question here is: what happens when another developer (or even author) must change this code few months later.
I would suggest modelling this as bit flags:
const int SCENARIO_1 = 0x0F; // 0b1111 if using c++14
const int SCENARIO_2 = 0x0E; // 0b1110
const int SCENARIO_3 = 0x08; // 0b1000
bool bValue1 = true;
bool bValue2 = false;
bool bValue3 = false;
bool bValue4 = false;
// boolean -> int conversion is covered by standard and produces 0/1
int scenario = bValue1 << 3 | bValue2 << 2 | bValue3 << 1 | bValue4;
bool match = scenario == SCENARIO_1 || scenario == SCENARIO_2 || scenario == SCENARIO_3;
std::cout << (match ? "ok" : "error");
If there are many more scenarios or more flags, a table approach is more readable and extensible than using flags. Supporting a new scenario requires just another row in the table.
int scenarios[3][4] = {
{true, true, true, true},
{true, true, true, false},
{true, false, false, false},
};
int main()
{
bool bValue1 = true;
bool bValue2 = false;
bool bValue3 = true;
bool bValue4 = true;
bool match = false;
// depending on compiler, prefer std::size()/_countof instead of magic value of 4
for (int i = 0; i < 4 && !match; ++i) {
auto current = scenarios[i];
match = bValue1 == current[0] &&
bValue2 == current[1] &&
bValue3 == current[2] &&
bValue4 == current[3];
}
std::cout << (match ? "ok" : "error");
}
My previous answer is already the accepted answer, I add something here that I think is both readable, easy and in this case open to future modifications:
Starting with #ZdeslavVojkovic answer (which I find quite good), I came up with this:
#include <iostream>
#include <set>
//using namespace std;
int GetScenarioInt(bool bValue1, bool bValue2, bool bValue3, bool bValue4)
{
return bValue1 << 3 | bValue2 << 2 | bValue3 << 1 | bValue4;
}
bool IsValidScenario(bool bValue1, bool bValue2, bool bValue3, bool bValue4)
{
std::set<int> validScenarios;
validScenarios.insert(GetScenarioInt(true, true, true, true));
validScenarios.insert(GetScenarioInt(true, true, true, false));
validScenarios.insert(GetScenarioInt(true, false, false, false));
int currentScenario = GetScenarioInt(bValue1, bValue2, bValue3, bValue4);
return validScenarios.find(currentScenario) != validScenarios.end();
}
int main()
{
std::cout << IsValidScenario(true, true, true, false) << "\n"; // expected = true;
std::cout << IsValidScenario(true, true, false, false) << "\n"; // expected = false;
return 0;
}
See it at work here
Well, that's the "elegant and maintainable" (IMHO) solution I usually aim to, but really, for the OP case, my previous "bunch of ifs" answer fits better the OP requirements, even if it's not elegant nor maintainable.
I would also like to submit an other approach.
My idea is to convert the bools into an integer and then compare using variadic templates:
unsigned bitmap_from_bools(bool b) {
return b;
}
template<typename... args>
unsigned bitmap_from_bools(bool b, args... pack) {
return (bitmap_from_bools(b) << sizeof...(pack)) | bitmap_from_bools(pack...);
}
int main() {
bool bValue1;
bool bValue2;
bool bValue3;
bool bValue4;
unsigned summary = bitmap_from_bools(bValue1, bValue2, bValue3, bValue4);
if (summary != 0b1111u && summary != 0b1110u && summary != 0b1000u) {
//bad scenario
}
}
Notice how this system can support up to 32 bools as input. replacing the unsigned with unsigned long long (or uint64_t) increases support to 64 cases.
If you dont like the if (summary != 0b1111u && summary != 0b1110u && summary != 0b1000u), you could also use yet another variadic template method:
bool equals_any(unsigned target, unsigned compare) {
return target == compare;
}
template<typename... args>
bool equals_any(unsigned target, unsigned compare, args... compare_pack) {
return equals_any(target, compare) ? true : equals_any(target, compare_pack...);
}
int main() {
bool bValue1;
bool bValue2;
bool bValue3;
bool bValue4;
unsigned summary = bitmap_from_bools(bValue1, bValue2, bValue3, bValue4);
if (!equals_any(summary, 0b1111u, 0b1110u, 0b1000u)) {
//bad scenario
}
}
Here's a simplified version:
if (bValue1 && (bValue2 == bValue3) && (bValue2 || !bValue4)) {
// acceptable
} else {
// not acceptable
}
Note, of course, this solution is more obfuscated than the original one, its meaning may be harder to understand.
Update: MSalters in the comments found an even simpler expression:
if (bValue1&&(bValue2==bValue3)&&(bValue2>=bValue4)) ...
Consider translating your tables as directly as possible into your program. Drive the program based off the table, instead of mimicing it with logic.
template<class T0>
auto is_any_of( T0 const& t0, std::initializer_list<T0> il ) {
for (auto&& x:il)
if (x==t0) return true;
return false;
}
now
if (is_any_of(
std::make_tuple(bValue1, bValue2, bValue3, bValue4),
{
{true, true, true, true},
{true, true, true, false},
{true, false, false, false}
}
))
this directly as possible encodes your truth table into the compiler.
Live example.
You could also use std::any_of directly:
using entry = std::array<bool, 4>;
constexpr entry acceptable[] =
{
{true, true, true, true},
{true, true, true, false},
{true, false, false, false}
};
if (std::any_of( begin(acceptable), end(acceptable), [&](auto&&x){
return entry{bValue1, bValue2, bValue3, bValue4} == x;
}) {
}
the compiler can inline the code, and eliminate any iteration and build its own logic for you. Meanwhile, your code reflects exactly how you concieved of the problem.
I am only providing my answer here as in the comments someone suggested to show my solution. I want to thank everyone for their insights.
In the end I opted to add three new "scenario" boolean methods:
bool CChristianLifeMinistryValidationDlg::IsFirstWeekStudentItems(CChristianLifeMinistryEntry *pEntry)
{
return (INCLUDE_ITEM1(pEntry) &&
!INCLUDE_ITEM2(pEntry) &&
!INCLUDE_ITEM3(pEntry) &&
!INCLUDE_ITEM4(pEntry));
}
bool CChristianLifeMinistryValidationDlg::IsSecondWeekStudentItems(CChristianLifeMinistryEntry *pEntry)
{
return (INCLUDE_ITEM1(pEntry) &&
INCLUDE_ITEM2(pEntry) &&
INCLUDE_ITEM3(pEntry) &&
INCLUDE_ITEM4(pEntry));
}
bool CChristianLifeMinistryValidationDlg::IsOtherWeekStudentItems(CChristianLifeMinistryEntry *pEntry)
{
return (INCLUDE_ITEM1(pEntry) &&
INCLUDE_ITEM2(pEntry) &&
INCLUDE_ITEM3(pEntry) &&
!INCLUDE_ITEM4(pEntry));
}
Then I was able to apply those my my validation routine like this:
if (!IsFirstWeekStudentItems(pEntry) && !IsSecondWeekStudentItems(pEntry) && !IsOtherWeekStudentItems(pEntry))
{
; Error
}
In my live application the 4 bool values are actually extracted from a DWORD which has 4 values encoded into it.
Thanks again everyone.
I'm not seeing any answers saying to name the scenarios, though the OP's solution does exactly that.
To me it is best to encapsulate the comment of what each scenario is into either a variable name or function name. You're more likely to ignore a comment than a name, and if your logic changes in the future you're more likely to change a name than a comment. You can't refactor a comment.
If you plan on reusing these scenarios outside of your function (or might want to), then make a function that says what it evaluates (constexpr/noexcept optional but recommended):
constexpr bool IsScenario1(bool b1, bool b2, bool b3, bool b4) noexcept
{ return b1 && b2 && b3 && b4; }
constexpr bool IsScenario2(bool b1, bool b2, bool b3, bool b4) noexcept
{ return b1 && b2 && b3 && !b4; }
constexpr bool IsScenario3(bool b1, bool b2, bool b3, bool b4) noexcept
{ return b1 && !b2 && !b3 && !b4; }
Make these class methods if possible (like in OP's solution). You can use variables inside of your function if you don't think you'll reuse the logic:
const auto is_scenario_1 = bValue1 && bValue2 && bValue3 && bValue4;
const auto is_scenario_2 = bvalue1 && bvalue2 && bValue3 && !bValue4;
const auto is_scenario_3 = bValue1 && !bValue2 && !bValue3 && !bValue4;
The compiler will most likely sort out that if bValue1 is false then all scenarios are false. Don't worry about making it fast, just correct and readable. If you profile your code and find this to be a bottleneck because the compiler generated sub-optimal code at -O2 or higher then try to rewrite it.
A C/C++ way
bool scenario[3][4] = {{true, true, true, true},
{true, true, true, false},
{true, false, false, false}};
bool CheckScenario(bool bValue1, bool bValue2, bool bValue3, bool bValue4)
{
bool temp[] = {bValue1, bValue2, bValue3, bValue4};
for(int i = 0 ; i < sizeof(scenario) / sizeof(scenario[0]); i++)
{
if(memcmp(temp, scenario[i], sizeof(temp)) == 0)
return true;
}
return false;
}
This approach is scalable as if the number of valid conditions grow, you easily just add more of them to scenario list.
It's easy to notice that first two scenarios are similar - they share most of the conditions. If you want to select in which scenario you are at the moment, you could write it like this (it's a modified #gian-paolo's solution):
bool valid = false;
if(bValue1 && bValue2 && bValue3)
{
if (bValue4)
valid = true; //scenario 1
else if (!bValue4)
valid = true; //scenario 2
}
else if (bValue1 && !bValue2 && !bValue3 && !bValue4)
valid = true; //scenario 3
Going further, you can notice, that first boolean needs to be always true, which is an entry condition, so you can end up with:
bool valid = false;
if(bValue1)
{
if(bValue2 && bValue3)
{
if (bValue4)
valid = true; //scenario 1
else if (!bValue4)
valid = true; //scenario 2
}
else if (!bValue2 && !bValue3 && !bValue4)
valid = true; //scenario 3
}
Even more, you can now clearly see, that bValue2 and bValue3 are somewhat connected - you could extract their state to some external functions or variables with more appropriate name (this is not always easy or appropriate though):
bool valid = false;
if(bValue1)
{
bool bValue1and2 = bValue1 && bValue2;
bool notBValue1and2 = !bValue2 && !bValue3;
if(bValue1and2)
{
if (bValue4)
valid = true; //scenario 1
else if (!bValue4)
valid = true; //scenario 2
}
else if (notBValue1and2 && !bValue4)
valid = true; //scenario 3
}
Doing it this way have some advantages and disadvantages:
conditions are smaller, so it's easier to reason about them,
it's easier to do nice renaming to make these conditions more understandable,
but, they require to understand the scope,
moreover it's more rigid
If you predict that there will be changes to the above logic, you should use more straightforward approach as presented by #gian-paolo.
Otherwise, if these conditions are well established, and are kind of "solid rules" that will never change, consider my last code snippet.
As suggested by mch, you could do:
if(!((bValue1 && bValue2 && bValue3) ||
(bValue1 && !bValue2 && !bValue3 && !bValue4))
)
where the first line covers the two first good cases, and the second line covers the last one.
Live Demo, where I played around and it passes your cases.
A slight variation on #GianPaolo's fine answer, which some may find easier to read:
bool any_of_three_scenarios(bool v1, bool v2, bool v3, bool v4)
{
return (v1 && v2 && v3 && v4) // scenario 1
|| (v1 && v2 && v3 && !v4) // scenario 2
|| (v1 && !v2 && !v3 && !v4); // scenario 3
}
if (any_of_three_scenarios(bValue1,bValue2,bValue3,bValue4))
{
// ...
}
Every answer is overly complex and difficult to read. The best solution to this is a switch() statement. It is both readable and makes adding/modifying additional cases simple. Compilers are good at optimising switch() statements too.
switch( (bValue4 << 3) | (bValue3 << 2) | (bValue2 << 1) | (bValue1) )
{
case 0b1111:
// scenario 1
break;
case 0b0111:
// scenario 2
break;
case 0b0001:
// scenario 3
break;
default:
// fault condition
break;
}
You can of course use constants and OR them together in the case statements for even greater readability.
I would also use shortcut variables for clarity. As noted earlier scenario 1 equals to scenario 2, because the value of bValue4 doesn't influence the truth of those two scenarios.
bool MAJORLY_TRUE=bValue1 && bValue2 && bValue3
bool MAJORLY_FALSE=!(bValue2 || bValue3 || bValue4)
then your expression beomes:
if (MAJORLY_TRUE || (bValue1 && MAJORLY_FALSE))
{
// do something
}
else
{
// There is some error
}
Giving meaningful names to MAJORTRUE and MAJORFALSE variables (as well as actually to bValue* vars) would help a lot with readability and maintenance.
Focus on readability of the problem, not the specific "if" statement.
While this will produce more lines of code, and some may consider it either overkill or unnecessary. I'd suggest that abstracting your scenarios from the specific booleans is the best way to maintain readability.
By splitting things into classes (feel free to just use functions, or whatever other tool you prefer) with understandable names - we can much more easily show the meanings behind each scenario. More importantly, in a system with many moving parts - it is easier to maintain and join into your existing systems (again, despite how much extra code is involed).
#include <iostream>
#include <vector>
using namespace std;
// These values would likely not come from a single struct in real life
// Instead, they may be references to other booleans in other systems
struct Values
{
bool bValue1; // These would be given better names in reality
bool bValue2; // e.g. bDidTheCarCatchFire
bool bValue3; // and bDidTheWindshieldFallOff
bool bValue4;
};
class Scenario
{
public:
Scenario(Values& values)
: mValues(values) {}
virtual operator bool() = 0;
protected:
Values& mValues;
};
// Names as examples of things that describe your "scenarios" more effectively
class Scenario1_TheCarWasNotDamagedAtAll : public Scenario
{
public:
Scenario1_TheCarWasNotDamagedAtAll(Values& values) : Scenario(values) {}
virtual operator bool()
{
return mValues.bValue1
&& mValues.bValue2
&& mValues.bValue3
&& mValues.bValue4;
}
};
class Scenario2_TheCarBreaksDownButDidntGoOnFire : public Scenario
{
public:
Scenario2_TheCarBreaksDownButDidntGoOnFire(Values& values) : Scenario(values) {}
virtual operator bool()
{
return mValues.bValue1
&& mValues.bValue2
&& mValues.bValue3
&& !mValues.bValue4;
}
};
class Scenario3_TheCarWasCompletelyWreckedAndFireEverywhere : public Scenario
{
public:
Scenario3_TheCarWasCompletelyWreckedAndFireEverywhere(Values& values) : Scenario(values) {}
virtual operator bool()
{
return mValues.bValue1
&& !mValues.bValue2
&& !mValues.bValue3
&& !mValues.bValue4;
}
};
Scenario* findMatchingScenario(std::vector<Scenario*>& scenarios)
{
for(std::vector<Scenario*>::iterator it = scenarios.begin(); it != scenarios.end(); it++)
{
if (**it)
{
return *it;
}
}
return NULL;
}
int main() {
Values values = {true, true, true, true};
std::vector<Scenario*> scenarios = {
new Scenario1_TheCarWasNotDamagedAtAll(values),
new Scenario2_TheCarBreaksDownButDidntGoOnFire(values),
new Scenario3_TheCarWasCompletelyWreckedAndFireEverywhere(values)
};
Scenario* matchingScenario = findMatchingScenario(scenarios);
if(matchingScenario)
{
std::cout << matchingScenario << " was a match" << std::endl;
}
else
{
std::cout << "No match" << std::endl;
}
// your code goes here
return 0;
}
It depends on what they represent.
For example if 1 is a key, and 2 and 3 are two people who must agree (except if they agree on NOT they need a third person - 4 - to confirm) the most readable might be:
1 &&
(
(2 && 3)
||
((!2 && !3) && !4)
)
by popular request:
Key &&
(
(Alice && Bob)
||
((!Alice && !Bob) && !Charlie)
)
Doing bitwise operation looks very clean and understandable.
int bitwise = (bValue4 << 3) | (bValue3 << 2) | (bValue2 << 1) | (bValue1);
if (bitwise == 0b1111 || bitwise == 0b0111 || bitwise == 0b0001)
{
//satisfying condition
}
I am denoting a, b, c, d for clarity, and A, B, C, D for complements
bValue1 = a (!A)
bValue2 = b (!B)
bValue3 = c (!C)
bValue4 = d (!D)
Equation
1 = abcd + abcD + aBCD
= a (bcd + bcD + BCD)
= a (bc + BCD)
= a (bcd + D (b ^C))
Use any equations that suits you.
If (!bValue1 || (bValue2 != bValue3) || (!bValue4 && bValue2))
{
// you have a problem
}
b1 must always be true
b2 must always equal b3
and b4 cannot be false
if b2 (and b3) are true
simple
Just a personal preference over the accepted answer, but I would write:
bool valid = false;
// scenario 1
valid = valid || (bValue1 && bValue2 && bValue3 && bValue4);
// scenario 2
valid = valid || (bValue1 && bValue2 && bValue3 && !bValue4);
// scenario 3
valid = valid || (bValue1 && !bValue2 && !bValue3 && !bValue4);
First, assuming you can only modify the scenario check, I would focus on readability and just wrap the check in a function so that you can just call if(ScenarioA()).
Now, assuming you actually want/need to optimize this, I would recommend converting the tightly linked Booleans into constant integers, and using bit operators on them
public class Options {
public const bool A = 2; // 0001
public const bool B = 4; // 0010
public const bool C = 16;// 0100
public const bool D = 32;// 1000
//public const bool N = 2^n; (up to n=32)
}
...
public isScenario3(int options) {
int s3 = Options.A | Options.B | Options.C;
// for true if only s3 options are set
return options == s3;
// for true if s3 options are set
// return options & s3 == s3
}
This makes expressing the scenarios as easy as listing what is part of it, allows you to use a switch statement to jump to the right condition, and confuse fellow developers who have not seen this before. (C# RegexOptions uses this pattern for setting flags, I don't know if there is a c++ library example)
Nested ifs could be easier to read for some people. Here is my version
bool check(int bValue1, int bValue2, int bValue3, int bValue4)
{
if (bValue1)
{
if (bValue2)
{
// scenario 1-2
return bValue3;
}
else
{
// scenario 3
return !bValue3 && !bValue4;
}
}
return false;
}
Several correct answers have been given to this question, but I would take a different view: if the code looks too complicated, something isn't quite right. The code will be difficult to debug and more likely to be "one-use-only".
In real life, when we find a situation like this:
Scenario 1 | Scenario 2 | Scenario 3
bValue1: true | true | true
bValue2: true | true | false
bValue3: true | true | false
bValue4: true | false | false
When four states are connected by such a precise pattern, we are dealing with the configuration of some "entity" in our model.
An extreme metaphor is how we would describe a "human beings" in a model, if we were not aware of their existence as unitary entities with components connected into specific degrees of freedom: we would have to describe independent states of of "torsoes", "arms", "legs" and "head" which would make it complicated to make sense of the system described. An immediate result would be unnaturally complicated boolean expressions.
Obviously, the way to reduce complexity is abstraction and a tool of choice in c++ is the object paradigm.
So the question is: why is there such a pattern? What is this and what does it represent?
Since we don't know the answer, we can fall back on a mathematical abstraction: the array: we have three scenarios, each of which is now an array.
0 1 2 3
Scenario 1: T T T T
Scenario 2: T T T F
Scenario 3: T F F F
At which point you have your initial configuration. as an array. E.g. std::array has an equality operator:
At which point your syntax becomes:
if( myarray == scenario1 ) {
// arrays contents are the same
}
else if ( myarray == scenario2 ) {
// arrays contents are the same
}
else if ( myarray == scenario3 ) {
// arrays contents are the same
}
else {
// not the same
}
Just as the answer by Gian Paolo, it short, clear and easily verifiable/debuggable. In this case, we have delegated the details of the boolean expressions to the compiler.
You won't have to worry about invalid combinations of boolean flags if you get rid of the boolean flags.
The acceptable values are:
Scenario 1 | Scenario 2 | Scenario 3
bValue1: true | true | true
bValue2: true | true | false
bValue3: true | true | false
bValue4: true | false | false
You clearly have three states (scenarios). It'd be better to model that and to derive the boolean properties from those states, not the other way around.
enum State
{
scenario1,
scenario2,
scenario3,
};
inline bool isValue1(State s)
{
// (Well, this is kind of silly. Do you really need this flag?)
return true;
}
inline bool isValue2(State s)
{
switch (s)
{
case scenario1:
case scenario2:
return true;
case scenario3:
return false;
}
}
inline bool isValue3(State s)
{
// (This is silly too. Do you really need this flag?)
return isValue2(s);
}
inline bool isValue4(State s)
{
switch (s)
{
case scenario1:
return true;
case scenario2:
case scenario3:
return false;
}
}
This is definitely more code than in Gian Paolo's answer, but depending on your situation, this could be much more maintainable:
There is a central set of functions to modify if additional boolean properties or scenarios are added.
Adding properties requires adding only a single function.
If adding a scenario, enabling compiler warnings about unhandled enum cases in switch statements will catch property-getters that don't handle that scenario.
If you need to modify the boolean properties dynamically, you don't need to re-validate their combinations everywhere. Instead of toggling individual boolean flags (which could result in invalid combinations of flags), you instead would have a state machine that transitions from one scenario to another.
This approach also has the side benefit of being very efficient.
The accepted answer is fine when you've only got 3 cases, and where the logic for each is simple.
But if the logic for each case were more complicated, or there are many more cases, a far better option is to use the chain-of-responsibility design pattern.
You create a BaseValidator which contains a reference to a BaseValidator and a method to validate and a method to call the validation on the referenced validator.
class BaseValidator {
BaseValidator* nextValidator;
public:
BaseValidator() {
nextValidator = 0;
}
void link(BaseValidator validator) {
if (nextValidator) {
nextValidator->link(validator);
} else {
nextValidator = validator;
}
}
bool callLinkedValidator(bool v1, bool v2, bool v3, bool v4) {
if (nextValidator) {
return nextValidator->validate(v1, v2, v3, v4);
}
return false;
}
virtual bool validate(bool v1, bool v2, bool v3, bool v4) {
return false;
}
}
Then you create a number of subclasses which inherit from the BaseValidator, overriding the validate method with the logic necessary for each validator.
class Validator1: public BaseValidator {
public:
bool validate(bool v1, bool v2, bool v3, bool v4) {
if (v1 && v2 && v3 && v4) {
return true;
}
return nextValidator->callLinkedValidator(v1, v2, v3, v4);
}
}
Then using it is simple, instantiate each of your validators, and set each of them to be the root of the others:
Validator1 firstValidator = new Validator1();
Validator2 secondValidator = new Validator2();
Validator3 thirdValidator = new Validator3();
firstValidator.link(secondValidator);
firstValidator.link(thirdValidator);
if (firstValidator.validate(value1, value2, value3, value4)) { ... }
In essence, each validation case has its own class which is responsible for (a) determining if the validation matches that case, and (b) sending the validation to someone else in the chain if it is not.
Please note that I am not familiar with C++. I've tried to match the syntax from some examples I found online, but if this does not work, treat it more like pseudocode. I also have a complete working Python example below that can be used as a basis if preferred.
class BaseValidator:
def __init__(self):
self.nextValidator = 0
def link(self, validator):
if (self.nextValidator):
self.nextValidator.link(validator)
else:
self.nextValidator = validator
def callLinkedValidator(self, v1, v2, v3, v4):
if (self.nextValidator):
return self.nextValidator.validate(v1, v2, v3, v4)
return False
def validate(self, v1, v2, v3, v4):
return False
class Validator1(BaseValidator):
def validate(self, v1, v2, v3, v4):
if (v1 and v2 and v3 and v4):
return True
return self.callLinkedValidator(v1, v2, v3, v4)
class Validator2(BaseValidator):
def validate(self, v1, v2, v3, v4):
if (v1 and v2 and v3 and not v4):
return True
return self.callLinkedValidator(v1, v2, v3, v4)
class Validator3(BaseValidator):
def validate(self, v1, v2, v3, v4):
if (v1 and not v2 and not v3 and not v4):
return True
return self.callLinkedValidator(v1, v2, v3, v4)
firstValidator = Validator1()
secondValidator = Validator2()
thirdValidator = Validator3()
firstValidator.link(secondValidator)
firstValidator.link(thirdValidator)
print(firstValidator.validate(False, False, True, False))
Again, you may find this overkill for your specific example, but it creates much cleaner code if you end up with a far more complicated set of cases that need to be met.
if(!bValue1)
return false;
if(bValue2 != bValue3)
return false;
if(bValue3 == false && bValuer4 == true)
return false;
return true;
My 2 cents: declare a variable sum (integer) so that
if(bValue1)
{
sum=sum+1;
}
if(bValue2)
{
sum=sum+2;
}
if(bValue3)
{
sum=sum+4;
}
if(bValue4)
{
sum=sum+8;
}
Check sum against the conditions you want and that's it.
This way you can add easily more conditions in the future keeping it quite straightforward to read.
use bit field:
unoin {
struct {
bool b1: 1;
bool b2: 1;
bool b3: 1;
bool b4: 1;
} b;
int i;
} u;
// set:
u.b.b1=true;
...
// test
if (u.i == 0x0f) {...}
if (u.i == 0x0e) {...}
if (u.i == 0x08) {...}
PS:
That's a big pity to CPPers'. But, UB is not my worry, check it at http://coliru.stacked-crooked.com/a/2b556abfc28574a1.

No return evaluation in nested if

After watching carefully the following code I can't see why the compiler is warning me with "warning: control reaches end of non-void function".
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
}
else
{
return false;
}
}
I can't see where is the problem, the else statement should care for returning false in every case which the first if is not true.
Trace the code path when regIOobject::read() is true, but either of permeabilityModelPtr_->read(subDict("permeability")) or magnetizationModelPtr_->read(subDict("magnetization")) is false. In that case, you enter the top if block (excluding the possibility of entering its attached else block), but then fail to enter the nested if block:
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
// Cool, read() was true, now check next if...
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
// Oh no, it was false, now we're here...
}
else
{
// First if was true, so we don't go here...
return false;
}
// End of function reached, where is the return???
}
The minimalist fix is to just remove the else { } wrapping, so any fallthrough ends up at return false;:
bool Foam::solidMagnetostaticModel::read()
{
if (regIOobject::read())
{
// Cool, read() was true, now check next if...
if (permeabilityModelPtr_->read(subDict("permeability")) && magnetizationModelPtr_->read(subDict("magnetization")))
{
return true;
}
// Oh no, it was false, now we're here...
}
// Oh, but we hit return false; so we're fine
return false;
}
Alternatively, avoid specifically mentioning true or false at all, since your function is logically just a result of anding three conditions together:
bool Foam::solidMagnetostaticModel::read()
{
// No need to use ifs or explicit references to true/false at all
return regIOobject::read() &&
permeabilityModelPtr_->read(subDict("permeability")) &&
magnetizationModelPtr_->read(subDict("magnetization"));
}
The nested if is the problem.
When that branch is not taken, there is no other paths to take
the else statement should care for returning false in every case which the first if is not true.
Correct, but what if the first if condition is true, but the second if condition is not?
That is: What if regIOobject::read() returns true, but permeabilityModelPtr_->read(subDict("permeability")) returns false?
Then the flow of control enters the first if block, does not return, but does not enter the else block (because the first condition was true), so it just falls off the end of the function without hitting a return statement.
If you want the else { return false; } part to apply to either condition, you could just naively copy/paste it:
if (COND1) {
if (COND2) {
return true;
} else {
return false;
}
} else {
return false;
}
But that's quite a bit of code duplication. A better solution is to replace the nested if by a single condition:
if (COND1 && COND2) {
return true;
} else {
return false;
}
There's still some duplication: Both branches consist of a return statement followed by some expression.
We can factor out the common parts (return) and push the condition into the expression:
return COND1 && COND2 ? true : false;
But ? true : false is redundant: If the condition is true, evaluate to true, else evaluate to false? Well, that's just what the condition itself does:
return COND1 && COND2;
Or with your concrete expressions:
return regIOobject::read()
&& permeabilityModelPtr_->read(subDict("permeability"))
&& magnetizationModelPtr_->read(subDict("magnetization"));

MQL4: Only half of my if/else if loop leads to current execution

I have this little function that is giving me trouble, only part of the function will follow my conditions at one time.
bool trend()
{
//is there a trend?
close1 = iClose(NULL,0,1); //vars
close2 = iClose(NULL,0,2);
close3 = iClose(NULL,0,3);
open1 = iOpen(NULL,0,1);
open2 = iOpen(NULL,0,2);
open3 = iOpen(NULL,0,3);
if(close3 > open3 && close2 > open2 && close1 > open1)
{
return(true); //uptrend
}
else if(close3 < open3 && close2 < open2 && close1 < open1)
{
return(false); //downtrend
}
else return(EMPTY_VALUE);
}
This is how the function gets called, under int start()
trending = trend();
if (trending == true) Order = SIGNAL_BUY; // Rule to ENTER a Long trade
if (trending == false) Order = SIGNAL_SELL; // Rule to ENTER a Short trade
As written above, my sell signal will work following the conditions, but the buy signals don't follow the conditions, and I can't figure out how they are triggering.
If I remove the "else return(EMPTY_VALUE);" then the buy orders start following the condition but the sell orders no longer follow the conditions. The broken sell order seems to behave like the broken buy order was.
Any ideas why my function is behaving like this? Thanks!
Your function is declared as bool trend(), which means that it can return either true or false. In the line else return(EMPTY_VALUE), the constant EMPTY_VALUE (which has the value 0x7FFFFFFF according to the MQL documentation) is implicitly converted to true. This means that your function will return true (which emits your buy signal) if there is no uptrend and no downtrend.
If you leave out the last line else return(EMPTY_VALUE) you have a missing return statement. This leads to undefined behaviour if you try to access the return value of the function, which you do in the line trending = trend().
To sum it up: Your problem is that the trend function can only return one of two values, true or false. But what you need is a function that returns one of three values uptrend, downtrend, no_trend. You could declare an enum with those three values and change the return type accordingly:
enum Trend {
UPTREND,
DOWNTREND,
NONE
}
Trend trend() {
// check if there is a trend
// [...]
if (close3 > open3 && close2 > open2 && close1 > open1) {
return UPTREND;
}
else if (close3 < open3 && close2 < open2 && close1 < open1) {
return DOWNTREND;
}
else {
return NONE;
}
}
and then later
Trend trending = trend();
if (trending == UPTREND) Order = SIGNAL_BUY;
if (trending == DOWNTREND) Order = SIGNAL_SELL;

Breaking out of if statement

I am writing a program in which I use an if statement to check some condition; if true I increment a counter. The problem is that as soon as the statement is true the variable either gets incremented endlessly or by random number.
I have been trying to use some clause to break out of this statement if condition meet but with no luck
my code:
if(res_vect_angle >=60 && res_vect_angle <=100 && left_mag_b >100)
{
//line(drawing, *iter_s, *(iter_s -1), Scalar( 255, 255, 255 ), 2,8 );
left_hook_count++;
cout<<"Left Hook:..........................!!! "<<left_hook_count<<endl;
if(left_hook_count++ == true)
{
break;
}
}
The whole chunk of code associated with the issue:
float M1, M2;
float A1, A2;
double left_mag_a, left_mag_b;
double res_vect_angle;
int i = 0;
for(vector<Point>::iterator iter_lh = Leftarm.begin(); iter_lh != Leftarm.end(); ++iter_lh)
{
if(iter_lh->y <=240 && iter_lh->y >=60 && iter_lh->x >=340 && iter_lh->x <=680)
{
left_detect.push_back(*iter_lh);
if(i % 4 == 0)
{
if(left_detect.size()>4)
{
for(vector<Point>::iterator iter_s = left_detect.begin()+3; iter_s != left_detect.end(); ++iter_s, i++)
{
//Resultant Magnetude
M1 = pow((double) iter_s->x + (iter_s -2)->x,2);
M2 = pow((double) iter_s->y + (iter_s -2)->y,2);
left_mag_a = (M1 + M2);
left_mag_b = sqrt(left_mag_a);
//Resultant Angle
A1 = abs(iter_s->x - (iter_s -2)->x);
A2 = abs(iter_s->y - (iter_s -2)->y);
res_vect_angle = abs(atan2(A1,A2) * 180 /PI);
//cout<<"LEFT HOOK ANGLE IS: "<<res_vect_angle<<endl;
if(res_vect_angle >=60 && res_vect_angle <=100 && left_mag_b >100)
{
//line(drawing, *iter_s, *(iter_s -1), Scalar( 255, 255, 255 ), 2,8 );
left_hook_count++;
cout<<"Left Hook:..........................!!! "<<left_hook_count<<endl;
if(left_hook_count++ == true)
{
break;
}
}
}
}
}
}
}
Hope this helps guys ps. left_hook_count++; is a int variable declared on top of my main().
The best solution is probably to invert the test, and make all the rest of the outer if conditional:
if (whatever) {
// do some stuff
if (left_hook_count != true) { // or whatever the test should really be
// do some more stuff
}
}
You could get the program flow you want using goto with a label after the outer if, but you don't want to.
On the other hand, it sounds like perhaps this is in a loop, and you don't want to enter the if block at all if the counter has been incremented? In that case you want:
if (left_hook_count == 0 && whatever) {
// do some stuff
}
you could provide more details so that we can figure out whats happening.
You might not have initialized it?
and checking again
if(left_hook_count++ == true)
it will increment it again unneccessariy and for for first count (0 : it wont happen)
i guess you 're using some recursive function. so check for Break condition (all test cases too).
Don't compare left_hook_count++ to true. In this context, true is equal to 1, and once left_hook_count exceeds 1, this test will fail and the code will never hit the break.
And you don't break out of an if statement. You break out of a loop; a break in an if statement inside the loop is one way of doing this.
You can just negate the condition, instead of trying to break out of the if:
if(...) {
if(!left_hook_count++) {
// Do what you need to do
}
}
my new answer:
:mylabel if (some_condition)
{
//code
if (some_condition) {break mylabel;}
//code
}
my old answer: Replace the if statement with a while statement containing a unconditional break at the end.
(old answer was before I learned of attaching labels to statement blocks.)
In your case:
while(res_vect_angle >=60 && res_vect_angle <=100 && left_mag_b >100)
{
//line(drawing, *iter_s, *(iter_s -1), Scalar( 255, 255, 255 ), 2,8 );
left_hook_count++;
cout<<"Left Hook:..........................!!! "<<left_hook_count<<endl;
if(left_hook_count++ == true)
{
break;
}
break; //this unconditional break makes the while loop act as an if statement
}
However if you don't have code after the conditional break what's the point of having it? I'm assuming you've omitted that code? The way you wrote it it would simply break out of the inner for loop.

C++ Try Catch inside loop

I have this C++ program with the following general structure
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
//condition B == false (supposed to leave 2nd loop and go back to first loop)
I want it to get out of 2nd loop when there's an exception and go back to 1st loop until condition B is tue again. As described above it doesn't work as I expect. What seems to be happening is that code gets stuck in catch and never leaves it.
How can I arrange it to make it work as I need?
Note: condition A is never false.
add the break keyword to the catch
Also notice that you have b == false;
That is checking that b is equal to false, not setting b = false.
bool flag1 = true, flag2 = true;
while (flag1)
{
// some work so that flag2 == true
while (flag2)
{
try
{
}
catch (...) // any exception happens
{
break;
}
}
}
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
{
//condition B == false (supposed to leave 2nd loop and go back to first loop)
break ;
}
Notice: Please do not use, even in examples, things like condition A == true. It is better to use while (condition A).
You can call break within the catch block to escape the second loop:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
while (B) {
try {
B = doSomethingElseThatMayThrow();
} catch (...) {
break;
}
}
}
}
Alternatively, you could place the second loop inside the try block:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
try {
while (B) {
B = doSomethingElseThatMayThrow();
}
} catch (...) {}
}
}