Check if only one string variable is not nullptr in C++ - c++

I have three LPCWSTR string variables called A, B, C.
I am assigning them from another function which can sometimes return nullptr if something goes wrong. like this:
A = MyFunc();
B = MyFunc();
C = MyFunc();
Now, for some stuff with those variables, I need to check if only one of these variables is not nullptr(only one of variables is assigned).
I tried to do this myself like:
if ((A == nullptr) && (B == nullptr) && (C <> nullptr)) {}
Any ideas about how to do this are welcome.

Easy enough to do with:
int numSet = 0;
A = MyFunc(); if (A != nullptr) numSet++;
B = MyFunc(); if (B != nullptr) numSet++;
C = MyFunc(); if (C != nullptr) numSet++;
if (numSet == 1) // only one is set
You could also encapsulate the behaviour with a helper function:
LPCWSTR MyFuncWithCount(int &countSetProperly) {
LPCWSTR retVal = MyFunc();
if (retVal != nullptr) countSetProperly++;
return retVal;
}
int numSet = 0;
A = MyFuncWithCount(numSet);
B = MyFuncWithCount(numSet);
C = MyFuncWithCount(numSet);
if (numSet == 1) // only one is set
Next step up from there would be using a range-based for loop in conjunction with a braced init list, as per the following complete program:
#include <iostream>
#include <vector>
typedef void * LPCWSTR; // Couldn't be bothered including Windows stuff :-)
int main() {
// Only set two for test purposes.
LPCWSTR A = nullptr, B = nullptr, C = nullptr;
LPCWSTR D = &A, E = nullptr, F = &A;
int numSet = 0;
for (const auto &pointer: {A, B, C, D, E, F})
if (pointer != nullptr)
numSet++;
std::cout << "Count is " << numSet << std::endl;
}
Or you could embrace modern C++ in all its glory by using lambda functions, as per the following:
#include <iostream>
#include <vector>
typedef void * LPCWSTR; // Couldn't be bothered including Windows stuff :-)
int main() {
// Only set two for test purposes.
LPCWSTR A = nullptr, B = nullptr, C = nullptr;
LPCWSTR D = &A, E = nullptr, F = &A;
int numSet = 0;
[&numSet](const std::vector<LPCWSTR> &pointers) {
for (const auto &pointer: pointers)
if (pointer != nullptr)
numSet++;
} (std::vector<LPCWSTR>{A,B,C,D,E,F});
std::cout << "Count is " << numSet << std::endl;
}
That's probably overkill for your particular case however :-)

With std, you may do:
const auto vars = {A, B, C}; // Create initializer list.
const bool onlyOneNotNull =
(std::count(vars.begin(), vars.end(), nullptr) == (vars.size() - 1);
// then you may use find_if to retrieve the non null variable.

Here's one simple way:
int not_null = 0;
not_null += A != nullptr;
not_null += B != nullptr;
not_null += C != nullptr;
if (not_null == 1) {
/* Do stuff */
}
Check each for being nullptr and increment a count if it is not. If the count comes out as 1 in the end, do your thing.

In C++, for backward-compatibility with C, the return value of a relational operator is an int equal to 0 or 1. So you can do:
if ( (a != nullptr) + (b != nullptr) + (c != nullptr) == 1 )
If you want to use logical operators only as logical operators, there are also disjunctive normal form and conjunctive normal form, albeit with more operations.
if ( (a && !b && !c) || (!a && b && !c) || (!a && !b && c) )
if ( (a || b || c) && (!a || !b) && (!a || !c) && (!b || !c) )
The former is not difficult to read in this simple case, compared to most of the other solutions, although it would quickly get too verbose if there were more possible solutions.
You can also stick them in any container, such as a std::array<LPCWSTR, 3>, and do std::count( pointers.begin(), pointers.end(), nullptr) (as Jarod42 suggested).

I'm not a huge fan of using techniques like the following in general, but you can use the fact that for any pointer ptr that !!ptr evaluates to 0 for a null pointer and 1 for a non-null pointer to write
if (!!A + !!B + !!C == 1) {
...
}
as a dense way to get this to work. It's essentially the same as #Davislor's solution but with a more compact "test if null" check.
This approach doesn't scale nearly as well as the accepted approach does, and it's trickier to read, but depending on your audience and who's reading the code it might do the trick nicely.

Related

How to properly check multiple times statment

if(a=='b' && b=='b' && c=='b' ...)
Is it the proper way to do this?
I already found other way to solve my problem but would like to know for future times how to do this
If all you have are discrete variables, then you'll have to do this check this way.
There are a few things you'll want to consider though:
It's bad practice to keep using 'b' over and over and over. Either assign it as a constant or have all the other variables compare against the first one, so that if you need to change that 'b' to a 'c' you only have to do it once in the code.
if(a=='b' && a == b && a == c && a == d/*...*/)
Also, this is still a lot of code to maintain. Depending on how long the chain goes (do you go up to a==g && a==h && a == i or further?) You might want to wrap those variables into a vector and iteratively check them.
bool equal = std::find_if_not(
characters.begin(), characters.end(),
[](const char & c) {return c == 'b';}
) == characters.end();
if you'd like a succinct way to describe intent then a little pair of template functions can help you:
template<class X, class Y>
bool all_equal(X&& x, Y&& y)
{
return (x == y);
}
template<class X, class Y, class...Rest>
bool all_equal(X&& x, Y&& y, Rest&&...rest)
{
return all_equal(std::forward<X>(x), std::forward<Y>(y))
&& all_equal(x, std::forward<Rest>(rest)...);
}
which allows code like this:
int main()
{
int a = 10;
int b = 10;
int c = 10;
int d = 11;
std::cout << std::boolalpha << all_equal(a, b) << std::endl;
std::cout << std::boolalpha << all_equal(a, b, c) << std::endl;
std::cout << std::boolalpha << all_equal(a, b, c, d) << std::endl;
}
Your way looks proper. Some coding standards require extra parens like this
if((a=='b') && (b=='b') && (c=='b') ...)
I personally don't think that it is necessary, if you know your operator precedence. see http://www.cppreference.com and search for precedence.

Generic variable to store varying levels of pointers

I want to write a generic centralized null-checker API for pointer type objects. I want to populate a list of my input pointer objects and call the null-checker API to scan through the list and validate if any pointer object is having NULL value. For this, I need to store varying levels of pointers in a single generic variable. How can I do that in C++ ?
template<typename type>
bool check(type& t)
{
return false;
}
template<typename type>
bool check(type* t)
{
return true;
}
int main()
{
char** doubleCharPointer = NULL;
char* charPointer = "charPointer";
doubleCharPointer = &charPointer;
char** temp = doubleCharPointer;
char* temp1 = NULL;
int count = 0;
if(!check(temp))
{
cout << "\nNot a pointer" << endl;
return 0;
}
temp1 = *temp;
count++;
if(!check(temp1))
{
cout << "\nPointer level : " << count << endl;
return 0;
}
count++;
cout << "\nPointer level : " << count << endl;
}
This is my null-checker prototype. It is very static at the moment. But I wanted to extend it to support any level of pointer checking. For that I need "temp" to be able to hold any level of pointer so that I can run an infinite while loop till all the levels of the input pointer is consumed and validated. How can I do that ? Please help.
I don't believe that there is a direct solution to this without knowing the exact numbers of levels. Let's say that you can advance level by level checking every level if it's NULL or not, however the main problem is that you don't know how far you must search, so in the end if you just go from address to address you may end up finding a NULL pointer or never ending your verification loop because you don't have a stop condition.
By doing this you may also access an unallocated memory address which may throw or not an exception, so you can't either use this thrown exception as a stop condition.
I think you want
template<typename T>
bool check_ptr_not_null(const T&)
{
return true; // not a pointer
}
template<typename T>
bool check_ptr_not_null(T* t)
{
return (t != nullptr) && check_ptr_not_null(*t);
}
Live Demo
Disclaimer: Do not up-vote this answer (dirty hack)
Expanding on A-B's answer, this is the best I can get to at the moment:
template<typename T>
bool notnull(T const *t, int level) {
while (level-- > 1) {
if (t == NULL)
return false;
t = (T const *)*t;
}
return t != NULL;
}
Note that this will induce some compiler warnings because of the line t = (T const *)*t so I guess this is unsafe. A cleaner way of doing this is just define some macros instead:
#define NOTNULL_P1(x) (x != NULL)
#define NOTNULL_P2(x) ((x != NULL) && NOTNULL_P1(*x))
#define NOTNULL_P3(x) ((x != NULL) && NOTNULL_P2(*x))
#define NOTNULL_P4(x) ((x != NULL) && NOTNULL_P3(*x))
#define NOTNULL_P5(x) ((x != NULL) && NOTNULL_P4(*x))

Check Array in MFC C++

This code that I have is not working as it should.
for (int i = 0; i <= 140; i++)
{
if (OneLine_Array.GetAt(i) == "Pass" || "Fail" || "Warn" || "Active")
{
OneLine_State.Add(OneLine_Array.GetAt(i));
}
}
It will work though if i have it as
for (int i = 0; i <= 140; i++)
{
if ((OneLine_Array.GetAt(i) == "Pass") || (OneLine_Array.GetAt(i) == "Fail") || (OneLine_Array.GetAt(i) == "Warn") || (OneLine_Array.GetAt(i) == "Active"))
{
OneLine_State.Add(OneLine_Array.GetAt(i));
}
}
I was wondering is there a shorter way of doing this rather than replicating the same line of code over and over again?
thanks.
You can store the result of GetAt before you get to the condition, then you don't need to evaluate it multiple times:
auto x = OneLine_Array.GetAt(i);
if (x == "Pass" || x == "Fail" || x == "Warn" || x == "Active")
For a sufficiently short variable name (but please call it something nicer than x), this will be shorter than your second example.
The reason your original condition doesn't work is because each of "Fail", "Warn", and "Active" are true, so the logical OR will also be true. They are true because they are of array type which can be converted to a pointer to their first elements (char*). A non-null pointer is converted to true.
you can't do this ( OneLine_Array.GetAt(i) == "Pass" || "Fail" || "Warn" || "Active") ==> this is not possible in C++
it will be better to save the string of the OneLine_Array.GetAt(i) in variable and make the "=="
Since you mention MFC C++. With a better performance, I'd suggest using CMap (http://msdn.microsoft.com/en-us/library/s897094z.aspx) to store your strings. It does speed up the comparision.
Although I prefer what #sftrabbit answered, you could write a little helper for this.
template<typename A, typename B>
bool equals_one_of(const A& a, const B& b)
{
return a == b;
}
template<typename A, typename B, typename... Args>
bool equals_one_of(const A& a, const B& b, const Args&... args)
{
return equals_one_of(a, b) || equals_one_of(a, args...);
}
int f()
{
if (equals_one_of(OneLine_Array.GetAt(i), "Pass", "Fail", "Warn", "Active"))
{
// ....
}
}

Similar Binary Trees

I have written the following function to check of two b-trees are similar or not. But I am not getting the desired output.
int bt_similar(btree *b1, btree *b2)
{
int m=1;
if ((b1->data==b2->data&&(((b1->lchild==NULL&&b2->lchild==NULL)||(b1->lchild!=NULL&&b2->lchild!=NULL))&&((b1->rchild==NULL&&b2->rchild==NULL)||(b1->rchild!=NULL&&b2->rchild!=NULL))))&&(m))
{
if (b1->lchild!=NULL)
m=bt_similar(b1->lchild,b2->lchild);
if (b1->rchild!=NULL)
m=bt_similar(b1->rchild,b2->rchild);
if (m)
return 1;
}
return 0;
}
Firstly, you could benefit a lot from breaking up your code, in particular that big condition in the if statement on the fourth line is nasty. Why not just handle the null case in the method itself? eg:
if (b1 == null && b2 != null)
return 0;
if (b2 == null && b1 != null)
return 0;
if (b1 == null && b2 == null)
return 1;
As far as I can tell, the actual problem with your code is where you overwrite the value of m at line 9, without taking the previous value into consideration. If the left-hand-side of the tree is not similar but the right is, the return will be 1. Instead of:
if (b1->lchild!=NULL)
m=bt_similar(b1->lchild,b2->lchild);
if (b1->rchild!=NULL)
m=bt_similar(b1->rchild,b2->rchild);
You should have:
if (b1->lchild!=NULL)
m = bt_similar(b1->lchild,b2->lchild);
if (b1->rchild!=NULL)
m = m && bt_similar(b1->rchild,b2->rchild);
you should make sure that if b1 == NULL or b2 == NULL...
bool compare(struct node* b1, struct node* b2) {
// 1. both empty -> true
if (b1==NULL && b2==NULL) return(true);
// 2. both non-empty -> compare them
else if (b1!=NULL && b2!=NULL) {
return(
b1->data == b2->data &&
compare(b1->lchild, b2->lchild) &&
compare(b1->rchild, b2->rchild));
}
// 3. one empty, one not -> false
else return false;
}
and, b-tree is not short for binary tree.

C++ "OR" operator

can this be done somehow?
if((a || b) == 0) return 1;
return 0;
so its like...if a OR b equals zero, then...but it is not working for me.
my real code is:
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) || p1.distanceFrom(l.p2)) <= r) {
return 1;
}
return 0;
}
You need to write the full expression:
(a==0)||(b==0)
And in the second code:
if((p1.distanceFrom(l.p1)<= r) || (p1.distanceFrom(l.p2)<=r) )
return 1;
If you do ((a || b) == 0) this means "Is the logical or of a and b equal to 0. And that's not what you want here.
And as a side note: the if (BooleanExpression)return true; else return false pattern can be shortened to return BooleanExpression;
You have to specify the condition separately each time:
if (a == 0) || (b == 0))
bla bla;
When you do
if ((a || b) == 0)
bla bla;
it has a different meaning: (a || b) means "if either a or b is non-zero (ie. true), then the result of this expression is true".
So when you do (a||b) == 0, you are checking if the result of the previously explained expression is equal to zero (or false).
The C++ language specifies that the operands of || ("or") be boolean expressions.
If p1.distanceFrom(l.p1) is not boolean (that is, if distanceFrom returns int, or double, or some numeric class type), the compiler will attempt to convert it to boolean.
For built in numeric type, the conversion is: non-zero converts to true, zero converts to false. If the type of p1.distanceFrom(l.p1) is of class type Foo, the compiler will call one (and only one) user defined conversion, e.g., Foo::operator bool(), to convert the expression's value to bool.
I think you really want something like this:
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
return 0;
}
Fun with templates:
template <typename T>
struct or_t
{
or_t(const T& a, const T& b) : value1(a), value2(b)
{
}
bool operator==(const T& c)
{
return value1 == c || value2 == c;
}
private:
const T& value1;
const T& value2;
};
template <typename T>
or_t<T> or(const T& a, const T& b)
{
return or_t<T>(a, b);
}
In use:
int main(int argc, char** argv)
{
int a = 7;
int b = 9;
if (or(a, b) == 7)
{
}
return 0;
}
It performs the same comparison you would normally do, though, but at your convenience.
If you have lot of that code, you may consider a helping method:
bool distanceLE (Point p1, Point p2, double threshold) {
return (p1.distanceFrom (p2) <= threshold)
}
bool Circle2::contains (Line2 l) {
return distanceLE (p1, l.p1, r) && distanceLE (p1, l.p2, r);
}
If you sometimes have <, sometimes <=, >, >= and so on, maybe you should pass the operator too, in form of a function.
In some cases your intentions by writing this:
if ((a || b) == 0) return 1;
return 0;
could be expressed with an bitwise-or:
if ((a | b) == 0) return 1;
return 0;
and simplified to
return ! (a | b);
But read up on bitwise operations and test it carefully. I use them rarely and especially I didn't use C++ for some time.
Note, that you inverted the meaning between your examples 1 and 2, returning true and false in the opposite way.
And bitwise less-equal doesn't make any sense, of course. :)
C++ doesn't support any construct like that. Use if (a == 0 || b == 0).
Your condition should be (a == 0 || b == 0) or (p1.distanceFrom(l.p1) <= r || p1.distanceFrom(l.p2)) <= r)
C++ isn't that smart. You have to do each comparison manually.
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
return 0;
}