Created
April 9, 2024 22:53
-
-
Save AndrewOfC/6ec3ff9c2fc4bfb1d6faa2a8eab550f8 to your computer and use it in GitHub Desktop.
ORing Values in C++ With Vararg Template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
One thing I like in like in languages like python and perl | |
is you can logically OR a series of values and it the | |
expression will result in the first one that is 'non null' | |
or 'true'. This facility is missing in C++ as the logical | |
or operator(||) produces a boolean. | |
One thing to be cautious of, is that in python and perl | |
evalution of the OR'd expressions stops on the first one | |
that is true, any further expressions are not evalutated, | |
to include any potential side effects. | |
In the case of this implementation each parameter expression | |
is evaluated before the first invocation of OR_VALUES is made. | |
Typically this will not be an issue if you're using it to evaluate | |
pointers or references that have already been allocated/constructed, | |
However, if used with temporary objects whose construction takes place | |
as the parameter | |
Examples: | |
using std::string ; | |
string s = OR_VALUES(string("a"), string("b"), string("c")) ; | |
All three parameters will be constructed before OR_VALUES is invoked. | |
*/ | |
/** | |
* Terminal expansion of OR_VALUES | |
* expanded when rest... only | |
* unpacks one argument. | |
*/ | |
template<typename Arg> | |
inline Arg OR_VALUES(const Arg& a) | |
{ | |
return a ; | |
} | |
/** | |
* Expansion for any OR_VALUES having | |
* two or more arguments | |
*/ | |
template<typename Arg, typename ... Rest> | |
inline Arg OR_VALUES(const Arg& a, Rest... rest) | |
{ | |
if( a ) // consume Arg a | |
return a ; | |
return OR_VALUES(rest...) ; | |
} | |
#ifdef EXAMPLE | |
#include <iostream> | |
using namespace std ; | |
int main(int, char**) | |
{ | |
auto n1 = (const char*)nullptr ; | |
auto n2 = (const char*)nullptr ; | |
auto n3 = (const char*)nullptr ; | |
auto foo = "foo" ; | |
auto foo2 = "foo2" ; | |
cout << OR_VALUES(foo) << endl ; | |
cout << OR_VALUES(n1, foo) << endl ; | |
cout << OR_VALUES(n1, n2, n3, foo) << endl ; | |
cout << OR_VALUES(n1, n2, foo2, foo, n3) << endl ; | |
return 0 ; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment