Optimizing loop and avoiding code duplication in a template specialization - c++

Assume we have a function
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(selector && selector(*pVal))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}
This looks bad because it will always enter the
if(selector && selector(*pVal))
even when it is NULL, an obvious approach to fix this would be :
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
if(selector)
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(selector(*pVal))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}
else
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
pVal->someOtherFunction(1,2,3);
//some more code
}
}
}
}
But this resulted in a lot of code duplication, another approach would be making a specialization for the case when the function is NULL but wouldnt that be almost identical as the example above? Is there another way of doing that without duplicating all the code ?

Your problem description is a bit confusing. You are not checking for NULL, because selector is not a pointer. Instead, you are checking to see if the boost::function object is empty() see: http://www.boost.org/doc/libs/1_55_0/doc/html/boost/function.html#idp54857000-bb.
Also, your two blocks of code are not equivalent. Your seem to indicate that you want to execute the inner loop if either (selector is provided and true) or (selector is not provided).
So, your first code block should be:
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(!selector || (selector && selector(*pVal)))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}
This is logically equivalent to your second block of code.
As Igor Tendetnik mentioned, you need to actually measure the code to see where the bottleneck is. It's likely not the checking for selector being empty.
If checking to see if the selector is empty really is your bottleneck, which is unlikely because the compiler with optimizations turned on is going to make those comparisons very fast inlined function calls, you could cache the result of the empty test.
template< typename A, typename B, typename C >
void function(vector<A>& keyContainer, int a, int b, int c, boost::function<bool(B&)> selector, C* objPointer = NULL)
{
bool check_selector = !selector.empty();
BOOST_FOREACH(const A& key, keyContainer)
{
B* pVal = someGetObjFunction(objPointer, key);
if(pVal)
{
if(!check_selector || (check_selector && selector(*pVal)))
{
pVal->someOtherFunction(1,2,3);
}
//some more code
}
}
}

Related

C++ Is there any guarantee that literals conditions generated by a template will be optimized away?

Excuse any mistakes in my code, I'm still learning C++ syntax. My question is not about whether the code is correct but whether a literal expression will be optimized away.
Let's say I have a function generated from a non-type template like this:
template <bool add>
int addIt(int a, int b) {
if (add) {
return a + b;
} else {
return a - b;
}
}
int v = addIt<true>(10, 5);
From my understanding, the compiler should expand the template to:
int addIt_someID(int a, int b) {
if (true) {
return a + b;
} else {
return a - b;
}
}
int v = addIt_someID(10, 5);
But since it now says if (true) it should be able to remove that entire branch, resulting in this:
void addIt_someID(int a, int b) {
return a + b;
}
int v = addIt_someID(10, 5);
This should be standard compiler behavior... but is this behavior well enough established that I can be certain of it from all major compilers?
I'm relying upon this behavior for a transpiler, and if it's not guaranteed I will have to implement it myself... if it is guaranteed I can let the C++ compiler to do it and that will save me a lot of time in having to parse and evaluate this myself.
This is never guaranteed for regular if (although I would say chaneces are pretty high). There are two ways to be sure. Simpler one requires C++17 (btw addIt seems to return wrong type):
template <bool add>
int addIt(int a, int b) {
if constexpr (add) {
return a + b;
} else {
return a - b;
}
}
int v = addIt<true>(10, 5);
if constexpr guerantees that this will be evaluated in compile time.
Another option is using template metaprogramming/explicit template specialization. For your code this would be pretty simple:
template <bool add>
int addIt(int a, int b);
template<> int addIt<true>(int a, int b) { return a + b; }
template<> int addIt<false>(int a, int b) { return a - b; }
int v = addIt<true>(10, 5);
For other cases you would need some more work like using std::enable_if and stuff like this

working with expressions: how to minimize runtime construction time

I have two classes, a single expression (SE) and a bundle of two expressions (ME). The bundle is an expression itself, hence it can be an element of another bundle.
struct SE {
SE(char id, char n) : id(id), n(n) {}
size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }
char id, n;
};
template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r) : lhs(l), rhs(r) { }
size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }
LHS lhs;
SE rhs;
};
The construction of the bundle performs a simple validity check based on the data member n, accessible in ME via the method size. An eval method does some claculations using the data member id. Neither n nor id are known at compile time.
For both classes I override the comma operator, so that it performs the recursive bundling of multiple single expression into a nested bundle.
auto SE::operator,(const SE& r) { return ME<SE>(*this, r); }
auto ME<LHS>::operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }
I want that, after the whole bundle has been constructed, the method eval is triggered on the whole bundle. Example:
SE('a',1); // prints 'a'
SE('a',1), SE('b',1); // prints '(a,b)'
SE('a',1), SE('b',1), SE('c',1); // prints '((a,b),c)'
A possible way to achieve that is to use the destructors of the classes and add a flag is_outer which is updated appropriately during contruction of SE and ME. When any of these class is destructed, if the flag indicates this is the outermost class, then eval is triggered. A full demo is given below.
Testing on godbolt the simple demo function below, it seems to me the compiler generates more code than strictly necessary. Although id and n are not known at compile time, the final type of the expression should be. I would expect the entire construction of the bundle to reduce to just moving a few numbers in the correct place, then check the assertions, but it seems to actually do much more copies.
Is it possible to obtain that more of the contruction part is produced at compile time?
#include <iostream>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;
// forward declaration
template <typename LHS> struct ME;
struct SE {
SE(char id, char n) : id(id), n(n), outer(true) {}
SE(const SE& expr) : id(expr.id), n(expr.n), outer(false) {}
ME<SE> operator,(const SE& r);
size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }
~SE() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='\n'; cout << b; } }
char id, n;
mutable bool outer;
};
template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r)
: lhs(l), rhs(r), outer(true) // tentatively set to true
{ l.outer = r.outer = false; assert(l.size() == r.size()); } // reset flag for arguments
ME(const ME<LHS>& expr)
: lhs(expr.lhs), rhs(expr.rhs), outer(false) {}
size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }
auto operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }
~ME() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='\n'; cout << b; } }
LHS lhs;
SE rhs;
mutable bool outer;
};
ME<SE> SE::operator,(const SE& r) { return ME<SE>(*this, r); }
void demo(char a, char na, char b, char nb, char c, char nc) {
SE(a, na), SE(b,nb), SE(c,nc); // prints '((a,b),c)'
}
int main() {
demo('a',1,'b',1,'c',1);
return 0;
}
The general pattern you are following is expression templates. Reading up on how others do it will help.
Usually expression templates use CRTP heavily, and do not store copies.
I believe I see bugs due to the copies.
Generally take T&& and store T& or T&&.
Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.
Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.
I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.

Best practice C++ metaprogramming: logic flow

Perhaps I've been spoiled by Ruby, but it seems to me that if I have two functions that use the same basic logic (but varying details), I should only have to write the logic out once -- and as a consequence, I should only have to maintain the code in one place.
Here is the basic logic, which I re-use in a number of different functions. The parts that change are labeled A, B, C, D, E, and F.
if (recursions) {
while (lcurr || rcurr) {
if (!rcurr || (lcurr && (lcurr->key < rcurr->key))) {
// A
lcurr = lcurr->next;
} else if (!lcurr || (rcurr && (rcurr->key < lcurr->key))) {
// B
rcurr = rcurr->next;
} else { // keys are == and both present
// C
lcurr = lcurr->next;
rcurr = rcurr->next;
}
}
} else {
while (lcurr || rcurr) {
if (!rcurr || (lcurr && (lcurr->key < rcurr->key))) {
// D
lcurr = lcurr->next;
} else if (!lcurr || (rcurr && (rcurr->key < lcurr->key))) {
// E
rcurr = rcurr->next;
} else { // keys == and both left and right nodes present
// F
lcurr = lcurr->next;
rcurr = rcurr->next;
}
}
}
The return values of the functions may be different, too. I'd like to be able to have additional logic as well in various places, if possible.
I realize that this can be done by way of C macros, but they don't seem particularly maintainable. I also realize that if my matrix type used nested STL lists, this might be easier. But is there any functionality in C++11 (or old C++) that allows this logic to be written only once? Could one do this with lambdas, perhaps?
The way I've seen this done is to write callback functions. So you would write the logic part once, much like you have in your second text block. You would also define functions A, B, C, D, E, and F.
In your logic function, you would pass in both the parameters required and pointers to the callback functions. Then, in the logic function, you would call these callbacks and pass them the parameters they need.
Quite honestly, this seems like it would be more work in the end. You would maintain a single point of truth for your logic, but function pointers can be a massive pain and reduce the readability of your code.
For the sake of providing as much information as possible, an example:
int addTwoNumbers(int a, int b) { //A simple adding function
return a + b;
}
int subtractTwoNumbers(int a, int b) { //A simple subtracting function
return a - b;
}
/*
* This is the fun one. The first argument is a pointer to a function. The other
* arguments are the numbers to do math with. They aren't as important.
* The important part is that, so long as the function declaration matches the one here
* (so a function that returns an int and takes in two ints as arguments) it can be
* used by this function
*/
void math(int (*mathFunc)(int, int), int one, int two) {
cout << *mathFunc(one, two);
}
int main(int argc, char* argv[]) {
int whichMath = 0; //Assume 1 is add, 2 is subtract
if(whichMath == 1) {
math(&addTwoNumbers, 5, 6); //we're going to add 5 and 6
} else {
math(&subtractTwoNumbers, 5, 6); // we're going to subtract 5 and 6
}
}
If that makes NO sense, then you are welcome to join the legions of us who struggle with function pointers. Again, I would say that you should just write the two separate functions, as you can see how ugly this will get.
As a disclaimer, I have not compiled this code. I'm at work and there is no c++ compiler on these machines.
I have used this site heavily in the past for reference on function pointers:
http://www.newty.de/fpt/fpt.html#defi
Well, one solution is to yank out the bit of redundant code and put it into a template, such as
template<T1, T2, T3>
bool TESTKEYS(T1 lcurr, T2 rcurr, T3 actor)
{
while (lcurr || rcurr) {
if (!rcurr || (lcurr && (lcurr->key < rcurr->key))) {
if (actor.TestLeft(....)) return false;
lcurr = lcurr->next;
} else if (!lcurr || (rcurr && (rcurr->key < lcurr->key))) {
if (actor.TestRight(....)) return false;
rcurr = rcurr->next;
} else { // keys == and both left and right nodes present
if (actor.TestBoth(....)) return false;
lcurr = lcurr->next;
rcurr = rcurr->next;
}
}
return true;
}
You will need to decide for yourself what parameters to use for the TestLeft, etc.
template<typename A, typename B, typename C>
void compute (/*some parameters */)
{
if (recursions) {
while (lcurr || rcurr) {
if (!rcurr || (lcurr && (lcurr->key < rcurr->key))) {
auto aResult = A (lcurr, rcurr);
lcurr = lcurr->next;
} else if (!lcurr || (rcurr && (rcurr->key < lcurr->key))) {
auto bResult = B (lcurr, rcurr);
} // ... and so on
C (aResult, bResult);
} // ... etc
}
To call compute you need to write classes you want to pass down in place of your A to F placeholder. The actual work is done in the operator() member function of each class.
class A1 {
public:
double operator() (SomeType t1, SomeType t2) {
// do work
}
};
class A2 {
public:
int operator() (SomeType t1, SomeType t2) {
// do work
}
};
class B1 {
public:
char* operator() (SomeType t1, SomeType t2) {
// do work
}
};
class B2 {
public:
SomeClass* operator() (SomeType t1, SomeType t2) {
// do work
}
};
class C1 {
public:
int operator() (double t1, char* t2) {
}
class C2 {
public:
int operator() (int t1, SomeClass* t2) {
}
compute<A1, B1, C1>(whatever);
compute<A2, B2, C2>(whatever);
Note how A1 and B1 return types match C1 arguments, and similarly for A2, B2 and C2.
auto requires C++11, if you cannot use it, you will have to do a little additional work:
class A1 {
public:
typedef double result_type;
double operator() (SomeType t1, SomeType t2) {
// do work
}
};
and inside compute
typename A::result_type aResult = A (lcurr, rcurr);

Executing code according to specific types in C++

I'm trying to rewrite some code I wrote time ago with a functional language (OCaml) into C++.
My problem can be shortened into:
I have a stack of values
a value can be of a variant type (so a set of different kinds of values, eg int, float, std::string, std::list whatever)
I want to define operators which work on the values (eg an addition operation which pops two values and pushes the sum of them)
some operators behaves differently according to the types which are found on the stack, ideally some operators even change the number of arguments according to the type (a simple example: addition operator could pop one value, if it's a std::list then push the operator applied between all values of the list, otherwise pops another value and do the addition if they're both float)
Up to now I've been able to make it work by using templates eg.
class Value
{
public:
Value(Type type) : type(type) { }
virtual string svalue() const = 0;
virtual string lvalue();
virtual bool equals(Value *value) const = 0;
virtual Value* clone() const = 0;
const Type type;
virtual ~Value() { };
}
template <class T>
class TValue : public Value
{
protected:
T value;
public:
TValue(Type type, T value) : Value(type), value(value) {}
void set(T value) { this->value = value; }
T get() const { return this->value; }
};
class Int : public TValue<int>
{
private:
public:
Int(int value) : TValue<int>(TYPE_INT, value) { };
virtual string svalue() const;
virtual bool equals(Value *value) const { return this->value == ((TValue<int>*)value)->get(); }
virtual Value *clone() const { return new Int(value); }
};
and then operators are interpreted by doing
Value *v1, *v2,
case OP_PLUS:
{
if (vm->popTwo(&v1, &v2))
{
switch (v1->type << 4 | v2->type)
{
case TYPES(TYPE_INT, TYPE_INT): vm->push(new Int(((Int*)v1)->get() + ((Int*)v2)->get())); break;
case TYPES(TYPE_FLOAT, TYPE_INT): vm->push(new Float(((Float*)v1)->get() + ((Int*)v2)->get())); break;
case TYPES(TYPE_INT, TYPE_FLOAT): vm->push(new Float(((Int*)v1)->get() + ((Float*)v2)->get())); break;
case TYPES(TYPE_FLOAT, TYPE_FLOAT): vm->push(new Float(((Float*)v1)->get() + ((Float*)v2)->get())); break;
}
}
break;
}
Now, this works but I don't like the approach because it sounds quite clumsy, it requires a lot of type casts and it is not elegant at all (compared to my functional implementation). I'm starting to looking into boost library to see if I can find a better way to manage everything, before starting with it I was trying to define a different way of defining operators such as
template <Opcode T, class X, class A>
class Unary
{
public:
static A* ptr(X* x)
{
cout << "Missing instruction!" << endl;
return NULL;
};
};
template <>
class Unary<OP_MINUS, Float, Float>
{
public:
static Float *ptr(Float *x) { return new Float(-x->get()); };
};
So that I'm able to do
Float *a = new Float(10);
Float *r = Unary<OP_MINUS, Float, Float>::ptr(f);
This works but I'm still unable to see how I am supposed to manage it in a generic way so that I can call the right function according to what is found on the stack and which operators is used.
Will boost help me somehow? What I would like to have is a solution that is type safe and elegant at the same time but boost has so many different libraries that is hard for me to just understand what to look for. I don't need to use it if there is something easier that I am missing, I didn't think to find so many difficulties when dropping a functional language for this kind of task.
You want boost::variant, and for the list-of-elements, boost::make_recursive_variant (so you can refer to the type inside the type).
While apply_visitor lets you apply a function to many types, I find something like this easier to think about to start (assuming C++11 support in your compiler):
template<typename T, typename Func, typename Types...>
bool TryApplyFuncOn( boost::variant<Types...>& var, Func f ) {
struct HelperVisitor {
HelperVisitor( Func f_ ):func(f_) {}
Func func;
typedef bool return_type;
template<typename U>
return_type operator()( U& unused ) { return false; }
return_type operator()( T& t ) { f(t); return true; }
};
return boost::apply_visitor( HelperVisitor(f), var );
}
which takes a type you want to apply a function on, and a variant, and applies it iff the type you asked to be applied is the type in the variant. It returns true if it found a match.
The general case lets you do this "in one pass".
So you can do something like:
// easy case:
typedef boost::variant<int,double> scalar;
scalar times_two(scalar const& left) {
scalar retval = left;
TryApplyFuncOn<int>( retval, []( int& value ){ value*=2; } );
TryApplyFuncOn<double>( retval, []( double& value ){ value*=2.; } );
return retval;
}
// tricky case:
scalar multiply(scalar const& left, scalar const& right) {
scalar retval = left;
TryApplyFuncOn<int>( retval, [&right]( int& left_value ){
TryApplyFuncOn<int>( right, [&left_value]( int& right_value ){
left_value *= right_value;
});
TryApplyFuncOn<double>( right, [&left_value]( double& right_value ){
left_value *= right_value;
});
});
TryApplyFuncOn<double>( retval, [&right]( double& left_value ){
TryApplyFuncOn<int>( right, [&left_value]( int& right_value ){
left_value *= right_value;
});
TryApplyFuncOn<double>( right, [&left_value]( double& right_value ){
left_value *= right_value;
});
});
return retval;
}
which doesn't yet do type promotion (so int*double doesn't become a double), but there isn't anything fundamental stopping that.
Make sense?

Generic way to cast int to enum in C++

Is there a generic way to cast int to enum in C++?
If int falls in range of an enum it should return an enum value, otherwise throw an exception. Is there a way to write it generically? More than one enum type should be supported.
Background: I have an external enum type and no control over the source code. I'd like to store this value in a database and retrieve it.
The obvious thing is to annotate your enum:
// generic code
#include <algorithm>
template <typename T>
struct enum_traits {};
template<typename T, size_t N>
T *endof(T (&ra)[N]) {
return ra + N;
}
template<typename T, typename ValType>
T check(ValType v) {
typedef enum_traits<T> traits;
const T *first = traits::enumerators;
const T *last = endof(traits::enumerators);
if (traits::sorted) { // probably premature optimization
if (std::binary_search(first, last, v)) return T(v);
} else if (std::find(first, last, v) != last) {
return T(v);
}
throw "exception";
}
// "enhanced" definition of enum
enum e {
x = 1,
y = 4,
z = 10,
};
template<>
struct enum_traits<e> {
static const e enumerators[];
static const bool sorted = true;
};
// must appear in only one TU,
// so if the above is in a header then it will need the array size
const e enum_traits<e>::enumerators[] = {x, y, z};
// usage
int main() {
e good = check<e>(1);
e bad = check<e>(2);
}
You need the array to be kept up to date with e, which is a nuisance if you're not the author of e. As Sjoerd says, it can probably be automated with any decent build system.
In any case, you're up against 7.2/6:
For an enumeration where emin is the
smallest enumerator and emax is the
largest, the values of the enumeration
are the values of the underlying type
in the range bmin to bmax, where bmin
and bmax are, respectively, the
smallest and largest values of the
smallest bit-field that can store emin
and emax. It is possible to define an
enumeration that has values not
defined by any of its enumerators.
So if you aren't the author of e, you may or may not have a guarantee that valid values of e actually appear in its definition.
Ugly.
enum MyEnum { one = 1, two = 2 };
MyEnum to_enum(int n)
{
switch( n )
{
case 1 : return one;
case 2 : return two;
}
throw something();
}
Now for the real question. Why do you need this? The code is ugly, not easy to write (*?) and not easy to maintain, and not easy to incorporate in to your code. The code it telling you that it's wrong. Why fight it?
EDIT:
Alternatively, given that enums are integral types in C++:
enum my_enum_val = static_cast<MyEnum>(my_int_val);
but this is even uglier that above, much more prone to errors, and it won't throw as you desire.
If, as you describe, the values are in a database, why not write a code generator that reads this table and creates a .h and .cpp file with both the enum and a to_enum(int) function?
Advantages:
Easy to add a to_string(my_enum) function.
Little maintenance required
Database and code are in synch
No- there's no introspection in C++, nor is there any built in "domain check" facility.
What do you think about this one?
#include <iostream>
#include <stdexcept>
#include <set>
#include <string>
using namespace std;
template<typename T>
class Enum
{
public:
static void insert(int value)
{
_set.insert(value);
}
static T buildFrom(int value)
{
if (_set.find(value) != _set.end()) {
T retval;
retval.assign(value);
return retval;
}
throw std::runtime_error("unexpected value");
}
operator int() const { return _value; }
private:
void assign(int value)
{
_value = value;
}
int _value;
static std::set<int> _set;
};
template<typename T> std::set<int> Enum<T>::_set;
class Apples: public Enum<Apples> {};
class Oranges: public Enum<Oranges> {};
class Proxy
{
public:
Proxy(int value): _value(value) {}
template<typename T>
operator T()
{
T theEnum;
return theEnum.buildFrom(_value);
}
int _value;
};
Proxy convert(int value)
{
return Proxy(value);
}
int main()
{
Apples::insert(4);
Apples::insert(8);
Apples a = convert(4); // works
std::cout << a << std::endl; // prints 4
try {
Apples b = convert(9); // throws
}
catch (std::exception const& e) {
std::cout << e.what() << std::endl; // prints "unexpected value"
}
try {
Oranges b = convert(4); // also throws
}
catch (std::exception const& e) {
std::cout << e.what() << std::endl; // prints "unexpected value"
}
}
You could then use code I posted here to switch on values.
You should not want something like what you describe to exist, I fear there are problems in your code design.
Also, you assume that enums come in a range, but that's not always the case:
enum Flags { one = 1, two = 2, four = 4, eigh = 8, big = 2000000000 };
This is not in a range: even if it was possible, are you supposed to check every integer from 0 to 2^n to see if they match some enum's value?
If you are prepared to list your enum values as template parameters you can do this in C++ 11 with varadic templates. You can look at this as a good thing, allowing you to accept subsets of the valid enum values in different contexts; often useful when parsing codes from external sources.
Perhaps not quite as generic as you'd like, but the checking code itself is generalised, you just need to specify the set of values. This approach handles gaps, arbitrary values, etc.
template<typename EnumType, EnumType... Values> class EnumCheck;
template<typename EnumType> class EnumCheck<EnumType>
{
public:
template<typename IntType>
static bool constexpr is_value(IntType) { return false; }
};
template<typename EnumType, EnumType V, EnumType... Next>
class EnumCheck<EnumType, V, Next...> : private EnumCheck<EnumType, Next...>
{
using super = EnumCheck<EnumType, Next...>;
public:
template<typename IntType>
static bool constexpr is_value(IntType v)
{
return v == static_cast<typename std::underlying_type<EnumType>::type>(V) || super::is_value(v);
}
EnumType convert(IntType v)
{
if (!is_value(v)) throw std::runtime_error("Enum value out of range");
return static_cast<EnumType>(v);
};
enum class Test {
A = 1,
C = 3,
E = 5
};
using TestCheck = EnumCheck<Test, Test::A, Test::C, Test::E>;
void check_value(int v)
{
if (TestCheck::is_value(v))
printf("%d is OK\n", v);
else
printf("%d is not OK\n", v);
}
int main()
{
for (int i = 0; i < 10; ++i)
check_value(i);
}
C++0x alternative to the "ugly" version, allows for multiple enums. Uses initializer lists rather than switches, a bit cleaner IMO. Unfortunately, this doesn't work around the need to hard-code the enum values.
#include <cassert> // assert
namespace // unnamed namespace
{
enum class e1 { value_1 = 1, value_2 = 2 };
enum class e2 { value_3 = 3, value_4 = 4 };
template <typename T>
int valid_enum( const int val, const T& vec )
{
for ( const auto item : vec )
if ( static_cast<int>( item ) == val ) return val;
throw std::exception( "invalid enum value!" ); // throw something useful here
} // valid_enum
} // ns
int main()
{
// generate list of valid values
const auto e1_valid_values = { e1::value_1, e1::value_2 };
const auto e2_valid_values = { e2::value_3, e2::value_4 };
auto result1 = static_cast<e1>( valid_enum( 1, e1_valid_values ) );
assert( result1 == e1::value_1 );
auto result2 = static_cast<e2>( valid_enum( 3, e2_valid_values ) );
assert( result2 == e2::value_3 );
// test throw on invalid value
try
{
auto result3 = static_cast<e1>( valid_enum( 9999999, e1_valid_values ) );
assert( false );
}
catch ( ... )
{
assert( true );
}
}