C++ automatic generation of switch statement - c++

Consider the following code
#include <iostream>
enum MyEnum{
A,
B,
END
};
template <int N>
class Trait {};
template<>
class Trait<A> {
public:
static int funct(int i) {return i*3;}
};
template<>
class Trait<B> {
public:
static int funct(int i) {return i*24;}
};
using namespace std;
int main(){
int i = 1;
switch(i){
case A: cout << Trait<A>::funct(i) << endl; break;
case B: cout << Trait<B>::funct(i) << endl; break;
}
}
Which will print 24 on the screen.
Assume now that I have many more values in the enum and that I define all the corresponding
template specializations of the class Trait.
To avoid writing all the code necessary in the switch statement I wrote a REPEAT macro which works almost like I want:
#include <iostream>
#define REPEAT(N, macro) REPEAT_##N(macro)
#define REPEAT_0(macro)
#define REPEAT_1(macro) REPEAT_0(macro) macro(0)
#define REPEAT_2(macro) REPEAT_1(macro) macro(1)
#define REPEAT_3(macro) REPEAT_2(macro) macro(2)
#define REPEAT_4(macro) REPEAT_3(macro) macro(3)
// etc...
// enum and class definitions
int main(){
#define MY_MACRO(N) case N: cout << Trait<N>::funct(i) << endl; break;
switch(i){
REPEAT(2, MY_MACRO)
}
}
The problem I have with this approach is that I cannot use
REPEAT(END, MY_MACRO)
because the preprocessor doesn't know about my enum.
Question: Is there a way to generate automatically the switch statement?
Notes:
The situation where I have to use this is much more complicated and having something automated would be really helpful.
It is important for me to use a switch statement because of the speed which can be achieved (speed is crucial for my application).
Thanks!
EDIT 1
More notes:
It is important that the generation of the switch depends on the value of END defined in the enum.
EDIT 2/3
I decided to make an addition here to explain better my application and why I prefer some solutions to others
In my real application the enum contains almost 50 different values and it will be extended in the future (hopefully by other people). The enum contains consecutive values.
the class "Trait" has more than 1 member function (currently 5). Furthermore, I need to use all this in 5 different files. If I don't use an automated way of generating what I need I end up writing many times code which is basically the same.
the member functions of Trait are used in the same way all the times.
currently, inside my switch I have a function call which looks like this (in1, in2 and out are all double passed by reference, const for the first two cases).
case A: Trait::funct(in1, in2, out); break;
Why do I like templates?
Consider the case Trait has 2 functions funct1 and funct2. I could define
template <int N>
class Trait {
public:
static int funct1(int i){static_assert(N!=N, "You forgot to define funct1");}
static int funct2(int i){static_assert(N!=N, "You forgot to define funct2");}
};
Now, if a function definition is missing, the compiler will return a meaningful error. When other people will make additions this will be helpful.
Using the method based on C++11 features suggested by Jarod42 I can avoid maintaining long arrays of function pointers which would be error prone.
Speed tests
So far I experimented with 3 solutions but with only two member functions in Trait:
the solution suggested by Jarod42
a simple array of function pointers as suggested by nndru and Ali
switch statement with the RETURN macro
The first two solutions seem to be equivalent, while the one based on the switch is 5 times faster. I used gcc version 4.6.3 with the flag -O3.

As you say, your enum is contiguous. In that case you don't need any templates or std::map or switch:
Use simply an array of function pointers and the enum as the index into the function pointer array!
#include <cassert>
#include <cstdio>
enum {
A,
B,
SIZE
};
int A_funct(int i) { return 3*i; }
int B_funct(int i) { return 24*i; }
typedef int (*enum_funct)(int );
enum_funct map[] = { A_funct, B_funct };
// In C++11 use this:
//static_assert( sizeof(map)/sizeof(map[0])==SIZE , "Some enum is missing its function!");
int main() {
assert(sizeof(map)/sizeof(map[0])==SIZE && "Some enum is missing its function!");
int i = 1;
std::printf("case A prints %d\n", map[A](i) );
std::printf("case B prints %d\n", map[B](i) );
}
UPDATE: From your comments:
My only concern about maintainability is about writing down explicitly
5 different function pointer arrays (if I don't automate this).
OK, now I understand the maintenance concern.
I believe you can only achieve this (no matter whether you use function pointer arrays or the switch approach) if you use some sort of source code generation, either with macros or write your own source code generator. You also have to work out some naming conventions so that the function pointer arrays (or the code at the case statements in the switch approach) can be automatically generated.
Since you didn't specify it, I just made up my own naming convention. If you are comfortable with macros, here is what I hacked together with the Boost Preprocessor Library by some mindless editing of the example:
#include <boost/preprocessor/repetition.hpp>
#define ENUM_SIZE 2
#define ENUM(z, n, unused) e##n,
enum {
BOOST_PP_REPEAT(ENUM_SIZE, ENUM, ~)
SIZE
};
#undef ENUM
int fA_e0(int i) { return 3*i; }
int fA_e1(int i) { return 24*i; }
int fB_e0(int i) { return 32*i; }
int fB_e1(int i) { return 8*i; }
typedef int (*enum_funct)(int );
#define MAP(z, n, case) f ## ##case ## _e##n,
enum_funct map_A[] = {
BOOST_PP_REPEAT(ENUM_SIZE, MAP, A)
};
enum_funct map_B[] = {
BOOST_PP_REPEAT(ENUM_SIZE, MAP, B)
};
#undef MAP
Here is what we get after the preprocessor resolved these macros (g++ -E myfile.cpp):
enum { e0, e1, SIZE };
[...]
typedef int (*enum_funct)(int );
enum_funct map_A[] = {
fA_e0, fA_e1,
};
enum_funct map_B[] = {
fB_e0, fB_e1,
};
So, as you can see, if you specify your own naming conventions, you can automatically generate the maps (function pointer arrays). The documentation is good.
However, if I were you, I would write my own source code generator. I would specify a simple text file format (key - value pairs on one line, separated by white space) and write my own tool to generate the desired C++ source files from this simple text file. The build system would then invoke my source code generator tool in the pre-build step. In that way, you don't have to mess with macros. (By the way, I wrote a little testing framework for myself and to circumvent the lack of reflection in C++ I use my own source code generator. Really not that difficult.)
The first two solutions seem to be equivalent, while the one based on
the switch is 5 times faster. I used gcc version 4.6.3 with the flag
-O3.
I would have to see your source code, the generated assembly and how you measured the time in order to understand how that happened.
So I also did my own speed tests. Since it would clutter this answer, the source codes are here: switch approach and the function pointer array approach.
As I expected: the switch approach is faster but only if you have a handful of branches. Andrei Alexandrescu also says the same in his talk
Writing Quick Code in C++, Quickly, at around 38 min. On my machine, the switch approach is as fast as the function pointer array approach if the enum size is 5. If the enum size is bigger than 5, the function pointer array approach is consistently faster. If the enum size is 200 and there are 10^8 function invocations, it is more than 10% faster on my machine. (The online codes have only 10^7 function invocations otherwise it times out.)
(I used link time optimization (-O3 -flto flag both to the compiler and the linker) and I can only recommend it; it gives a nice performance boost (in my codes up to 2.5x) and the only thing you need to do is to pass one extra flag. However, in your case the code was so simple that it didn't change anything. If you wish to try it: The link time optimization is either not available or only experimental in gcc 4.6.3.)
From your comments:
I made new experiments following step by step your benchmark method
but I still get better results with the switch statement (when the
enum size is 150 the switch is still almost twice as fast as than the
solution with pointers). [...]
In the test with my code the switch method performs always better. I run also some
experiments with your code and I got the same kind of results you got.
I have looked at the generated assembly codes, having at least 5 functions (5 cases). If we have at least this many functions, roughly speaking, what happens is that the compiler turns the switch approach into the function pointer approach with one significant disadvantage. Even in the best case, the switch always goes through 1 extra branch (integer comparison potentially followed by a jump) compared to the hand-coded function pointer array approach when dispatching to the function to be called. This extra branch belongs to the default: label which is generated even if you deliberately omit it in the C++ code; there is no way to stop the compiler from generating the code for this. (If you have at most 4 cases and all 4 function calls can be inlined, then it is different; however you already have 50 cases so it doesn't matter.)
Apart from that, with the switch approach, additional (redundant) instructions and paddings are generated, corresponding to the code at the case: labels. This potentially increases your cache misses. So, as I see it, the the switch is always inferior to the function pointer approach if you have more than a handful of cases (5 cases on my machine). That is what Andrei Alexandrescu says in his talk too; he gives a limit of ~7 cases.
As for the reasons why your speedtests indicate the opposite: These sort of speed testings are always unreliable because they are extremely sensitive to alignment and caching. Nevertheless, in my primitive tests, the switch approach was always slightly worse than the function pointer array, which is in agreement with my above analysis of the assembly codes.
Another advantage of the function pointer arrays is that it can be built and changed at runtime; this is something that you don't get with the switch approach.
The weird thing is that the speed I get with the function pointer
array changes depending on the enum size (I would expect it to be
roughly constant).
As the enum size grows, you have more functions and the instruction cache misses are more likely to happen. In other words, the program should run slightly slower if you have more functions. (It does on my machine.) Of course the whole thing happens at random, so there will be significant deviations, don't be surprised if it runs faster for ENUM_SIZE=42 than for 41. And as mentioned earlier, alignment adds additional noise to this.

In C++11, you may do the following:
#if 1 // Not in C++11
#include <cstdint>
template <std::size_t ...> struct index_sequence {};
template <std::size_t I, std::size_t ...Is>
struct make_index_sequence : make_index_sequence < I - 1, I - 1, Is... > {};
template <std::size_t ... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> {};
#endif
namespace detail {
template <std::size_t ... Is>
int funct(MyEnum e, int i, index_sequence<Is...>)
{
// create an array of pointer on function and call the correct one.
return std::array<int(*)(int), sizeof...(Is)>{{&Trait<MyEnum(Is)>::funct...}}[(int)e](i);
}
} // namespace detail
int funct(MyEnum e, std::size_t i)
{
return detail::funct(e, i, make_index_sequence<std::size_t(END)>());
}
Note: enum should not have hole (so here A=0 and B=1 is ok)
Following macro may help:
#define DYN_DISPATCH(TRAIT, NAME, SIGNATURE, ENUM, ENUM_END) \
namespace detail { \
template <std::size_t ... Is> \
constexpr auto NAME(ENUM e, index_sequence<Is...>) -> SIGNATURE \
{ \
return std::array<SIGNATURE, sizeof...(Is)>{{&TRAIT<ENUM(Is)>::NAME...}}[(int)e]; \
} \
} /*namespace detail */ \
template <typename...Ts> \
auto NAME(ENUM e, Ts&&...ts) \
-> decltype(std::declval<SIGNATURE>()(std::declval<Ts>()...)) \
{ \
return detail::NAME(e, make_index_sequence<std::size_t(ENUM_END)>())(std::forward<Ts>(ts)...); \
}
And then use it as:
DYN_DISPATCH(Trait, funct, int(*)(int), MyEnum, END)
// now `int funct(MyEnum, int)` can be call.

You don't need templates at all to do this. More like good old X macros
#define MY_ENUM_LIST VAL(A) VAL(B)
// define an enum
#define VAL(x) x,
enum MyEnum { MY_ENUM_LIST END };
#undef VAL
// define a few functions doing a switch on Enum values
void do_something_with_Enum (MyEnum value, int i)
{
switch (value)
{
#define VAL(N) case N: std::cout << Trait<N>::funct(i) << std::endl; break;
MY_ENUM_LIST
#undef VAL
}
}
int do_something_else_with_Enum (MyEnum value)
{
switch (value)
{
#define VAL(x) case x: yet_another_template_mayhem(x);
MY_ENUM_LIST
#undef VAL
}
}
I've wasted enough time with this already. If you think templates are the solution, simply change your question to "templates experts only, preprocessor not good enough" or something.
You will not be the first wasting your time on useless templates. Many people make a fat living on providing bloated, useless solutions to inexisting problems.
Besides, your assumption of a switch being faster than an array of function pointers is highly debatable. It all depends on the number of values in your enum and the variability of the code inside your case statements.
Now if optimization is not such a big issue, you can simply use virtual methods to specialize the behaviour of whatever objects are selected by your enum and let the compiler handle the whole "automatic switch" stuff for you.
The only benefit of this approach is to avoid duplicating code if your objects are similar enough to make you think you will do a better job than the compiler handling them in a specialized way.
What you seem to be asking for is a generic solution for optimizing an unknown code pattern, and that is a contradiction in terms.
EDIT: thanks to Jarod42 for cleaning up the example.

It looks like you would like to associate and integer id with each function and find functions by the id.
If your id's are sequential you can have an array of function pointers indexed by that id, which would give you O(1) lookup complexity, e.g.:
typedef int Fn(int);
enum FnId {
A,
B,
FNID_COUNT
};
int fn_a(int);
int fn_b(int);
Fn* const fns[FNID_COUNT] = {
fn_a,
fn_b
};
int main() {
fns[A](1); // invoke function with id A.
}
If the id's are not sequential, you can still have a sorted array of {id, function_ptr} tuples and do binary search on it, O(lg(N)) lookup complexity.
None of these require macros or templates.

For numeric (database) type identifiers I have a template holding the identifiers. A dispatch via variadic templates calls a functor with the matching type traits:
#include <iostream>
#include <stdexcept>
// Library
// =======
class TypeIdentifier
{
public:
typedef unsigned Integer;
enum Value
{
Unknown,
Bool,
Int8,
UInt8,
Int16,
UInt16,
Int32,
UInt32,
Int64,
UInt64,
Float,
Double,
String,
LargeObject,
Date,
Time,
DateTime
};
template <Value ...Ids> struct ListType {};
typedef ListType<
Bool,
Int8,
UInt8,
Int16,
UInt16,
Int32,
UInt32,
Int64,
UInt64,
Float,
Double,
String,
LargeObject,
Date,
DateTime,
// Always the last value:
Unknown
>
List;
public:
TypeIdentifier(Integer value = Unknown)
: m_id(value)
{}
Integer id() const { return m_id; }
/// Involve a functor having a member function 'Result apply<Traits>()'.
template<typename Functor>
typename Functor::result_type dispatch(const Functor&);
private:
Integer m_id;
};
template<TypeIdentifier::Value I>
struct TypeTraits
{
static constexpr TypeIdentifier::Value Id = I;
static constexpr bool is(TypeIdentifier::Integer id) { return (Id == id); }
static bool is(TypeIdentifier type_identifier) { return (Id == type_identifier.id()); }
// And conversion functions
};
namespace TypeIdentifierDispatch {
template <typename Functor, TypeIdentifier::Value I, TypeIdentifier::Value ... Ids> struct Evaluate;
template <typename Functor>
struct Evaluate<Functor, TypeIdentifier::Unknown> {
static typename Functor::result_type
apply(TypeIdentifier::Integer id, const Functor&) {
throw std::logic_error("Unknown Type");
}
};
template <typename Functor, TypeIdentifier::Value I, TypeIdentifier::Value ... Ids>
struct Evaluate {
static typename Functor::result_type
apply(TypeIdentifier::Integer id, const Functor& functor) {
if(TypeTraits<I>::is(id))
return functor.template apply<TypeTraits<I>>();
else return Evaluate<Functor, Ids...>::apply(id, functor);
}
};
template <typename Functor, TypeIdentifier::Value ... Ids>
inline typename Functor::result_type
evaluate(TypeIdentifier::Integer id, const Functor& functor, TypeIdentifier::ListType<Ids...>)
{
return Evaluate<Functor, Ids...>::apply(id, functor);
}
} // namespace TypeIdentifierDispatch
template<typename Functor>
inline
typename Functor::result_type TypeIdentifier::dispatch(const Functor& functor) {
return TypeIdentifierDispatch::evaluate(id(), functor, TypeIdentifier::List());
}
// Usage
// =====
struct Print {
typedef void result_type;
template <typename Traits>
result_type apply() const {
std::cout << "Type Identifier: " << Traits::Id << '\n';
}
};
inline void print_identifier(unsigned value) {
TypeIdentifier(value).dispatch(Print());
}
int main ()
{
print_identifier(TypeIdentifier::String);
return 0;
}
Adding a new type to the library requires adjusting TypeIdentfier and (maybe) adding a specialized TypeTraits.
Note the enum values can be arbitrary.

Using recursive template you can automatically generate construction equivalent to
if (i = A)
Trait<A>::funct(i);
else if (i = B)
Trait<B>::funct(i);
I think it performance is similar to switch statement. Your original example can be rewritten as below.
#include <iostream>
using namespace std;
enum MyEnum {
A,
B,
END
};
template <MyEnum N>
class Trait
{ public:
static int funct(int i)
{
cout << "You forgot to define funct" << i;
return i;
}
};
template<>
class Trait<A> {
public:
static int funct(int i) { return i * 3; }
};
template<>
class Trait<B> {
public:
static int funct(int i) { return i * 24; }
};
template <MyEnum idx>
int Switch(const MyEnum p, const int n)
{
return (p == idx) ? Trait<idx>::funct(n) : Switch<(MyEnum)(idx - 1)>(p, n);
}
template <>
int Switch<(MyEnum)(0)>(const MyEnum p, const int n)
{
return Trait<(MyEnum)(0)>::funct(n);
}
int funct(MyEnum n)
{
return Switch<END>(n, n);
}
int main() {
MyEnum i = B;
cout << funct(i);
}

Related

Control dimension of vector at run time

I am working on a program that needs to be able to create vectors with different dimensions at runtime. I know that C++ templates are a compile time feature, and I am not sure how to work around this currently. I have seen some examples that use if statements to control the allocation of memory like so:
if (some_condition == 1) {
std::vector<int> x;
} else if (some_condition == 2) {
std::vector<std::vector<int>> x;
} // repeat for how ever many times
This works fine as a temporary solution, but I would really like there to be a way to control the dimension of a created vector without brute forcing if else statements up to some arbitrary number. If it is not possible would it be possible to make my own vector class, but with fixed types? I have tried making a 1 dimensional vector and using math to index it like a multi dimensional vector, but this seems to get complicated fast.
template<typename class_name>
class rvector
{
std::vector<class_name> items;
int depth;
// Some collection type that lays out the format of all the items
}
This is a way to implement the recursive template application:
#include <iostream>
#include <vector>
#include <type_traits>
template<typename T>
struct ID {};
template<size_t i, typename U>
auto n_dim_vec_gen(U u)
{
if constexpr (i) {
return n_dim_vec_gen<i - 1>(std::vector<U>());
} else {
return u;
}
}
template<typename T, size_t i>
using n_dim_vec = decltype(n_dim_vec_gen<i>(std::declval<T>()));
static_assert(std::is_same<n_dim_vec<int, 1>, std::vector<int>>::value);
static_assert(std::is_same<n_dim_vec<int, 2>, std::vector<std::vector<int>>>::value);
If you'd also like to standardize the some_condition processing, then you need to make a runtime - to - compile-time bridge (a simple switch statement works) and then apply the lambda. You might generate the branches of the switch using e.g. BOOST_PP_FOREACH, but that might be a little overkill. Then apply the pre-defined lambda.
auto whatToDo = [&](auto x, auto depth) {
// note that depth's type is compile-time
// integral_constant, so you can use it in e.g.
// if constexpr and template arguments
n_dim_vec<int, depth> x;
// ...
};
// this is the runtime - to - compile-time bridge
switch (some_condition) {
#define CASE(I) case I: whatToDo(std::integral_constant<int, I>()); break;
CASE(1)
CASE(2)
CASE(3)
// ...
#undef CASE
};

How to call a function from an object with a std::string

Here's my issue, I would like to call the getters/setters of one of my objects, but not directly, I want to do it by using a std::string.
I found this but it won't work on my case I think it is because my function aren't defined in my main method but in my square class. Also my function are not all defined the same way there's void(std::string) std::string() void(int)...
here's an exemple of what a would like to do.
my object square
#include <map>
#include <functional>
#include <string>
class Square{
private:
std::string name;
int width;
float happinessPoint; //extremly important for your square.
public:
void setName(std::string);
void setWidth(int);
void setHappinessPoint(float);
std::string getName()
int getWidth()
float getHappinnessPoint()
}
and my main
#include "Square.h/cpp"
int main(){
Square square = Square("Roger",2,3.5);
// here in my magicalFunction I ask to the users the new values for my square (all in std::string for now)
vector <std::string> newValueForSquare = magicalFunction();
for (unsigned int i=0; i < newValueForSquare.size(), i++){
//here I have a function which tell me if my std::string
// is in fact a float or an int
// and I would like to call each of my setters one by one to
// sets my Square to some value I asked to the user before all that.
// something like that:
// someFunction("setName","Henry")
}
}
I hope i have been clear it's pretty hard to explain something you don't know how to do. If you want me to be more specific tell me and I'll do what I can.
EDIT: What I want to do is to call for example my square.setName() with a str::string without writting this square.setName in my main.
To call functions, based on a string, you have some choices. Before I list the choices, please search the internet for "C++ factory design pattern".
If-else ladder
Lookup table
Map / Associative array
Hash table
There may be other methods, but the above come to mind.
if-else ladder (a.k.a. switch)
The problem with this method is that the switch statement doesn't work with strings nor text literals. So you'll have to suffice with if statements:
if (string == "Roger")
{
Process_Roger();
}
else if (string == "Felicity")
{
Process_Felicity();
}
else
{
Display_Error_Message();
}
Anytime you need to add a new string, you will have to add another "else if" statement to the ladder. Not only do you have to change the code, but you also have to retest it.
Lookup Table
You will need to understand function pointers for this technique and the map technique. Consider this a prerequisite.
Use a structure for mapping text strings to function pointers:
struct Text_Function_Pointer
{
const char * name;
Function_Pointer p_function;
};
static const Text_Function_Pointer table[] =
{
{"Larry", Process_Larry},
{"Felicity", Process_Felicity},
};
static const unsigned int table_size =
sizeof(table) / sizeof(table[0]);
//...
for (unsigned int i = 0; i < table_size; ++i)
{
if (search_name == table[i].name)
{
// Execute the processing function.
table[i].p_function(search_name);
break;
}
}
An issue with this technique is that all the function pointers must have the same signature. This is true for the map as well.
A nice feature is that the data in the table is constant, so it can be placed in Read-Only Memory.
Also, to add more associations, add an entry to the the table. The search / processing function hasn't changed, so it doesn't need to be tested again.
Map / Associative Array
Prerequisite: Function pointers.
Declare a std::map<std::string, Function_Pointer_Type>. Add your names and functions to the map:
std::map<std::string, Function_Pointer_Type> dispatch_table;
dispatch_table["Roger"] = Process_Roger;
dispatch_table["Felicity"] = Process_Felicity;
dispatch_table["Larry"] = Process_Larry;
//...
// Execute appropriate processing function:
(dispatch_table[search_name])();
One issue with this method is that the std::map data structure needs to be initialized; it can't be directly accessed or loaded from executable code.
Again, all functions must have the same signature.
Hash Table
The idea here is to have an array of function pointers or an array of structures with text & function pointers. Create a hash function that generates a unique array index based on the name string. Use the index to get the function pointer from the array, then execute the function via the function pointer.
Several solutions are available to you. You basically want to parse user input to fill your Square class attribute.
One way is to use the std::stoi family of functions:
std::vector<string> values { "Roger", "2", "3.5" };
std::string name = values[0]; // No problem, two strings
int width = std::stoi(values[1]); // stoi = stringToInt
float happiness = std::stof(values[2]); // stof = stringToFloat
I'm not sure why you'd need the for loop, unless there is something I didn't understand in your question. I'll update my answer accordingly.
Update 1
After reading other answers, I would like to propose my solution to your problem. As stated several times in my comments, this is not an easy answer !
I needed such a class to write a generic test engine, and this is the code I used. It works really well with any type of function (except for routines with a return type of void -- a simple template specialization would solve it though)
# include <functional>
# include <tuple>
template<int ...>
struct seq
{
};
template<int N, int ...S>
struct gens : gens<N - 1, N - 1, S...>
{
};
template<int ...S>
struct gens<0, S...>
{
typedef seq<S...> type;
};
struct callable_base
{
virtual void operator()() = 0;
virtual ~callable_base()
{ }
};
class Task
{
private:
template<class RT, class Functor, class ...Args>
struct functor : public callable_base
{
functor(RT& result, Functor func, Args ...args)
: _ret(result)
{
_func = func;
_args = std::make_tuple(args...);
}
void operator()()
{
_ret = call(typename gens<sizeof...(Args)>::type());
}
template<int ...S>
RT call(seq<S...>)
{
return (_func(std::get<S>(_args)...));
}
private:
std::function<RT(Args...)> _func;
std::tuple<Args...> _args;
RT& _ret;
};
public:
Task()
{
_functor = nullptr;
}
template<class RT, class Functor, class ...Args>
Task(RT& result, Functor func, Args... args)
{
_functor = new functor<RT, Functor, Args...>(result, func, args...);
}
void operator()()
{
(*_functor)();
}
~Task()
{
delete _functor;
}
private:
callable_base *_functor;
};
The idea behind this code is to hide the function signature in the inner class Task::functor and get the return value in the first parameter passed to the Task(...) constructor. I'm giving this code first because I think it might help some people, but also because I think it is an elegant solution to your problem. Bear in mind that to understand most of the code, you need solid C++ knowledge. I'll detail the code in subsequent updates if needed.
Here's how you'd use it:
int main()
{
int retVal;
std::string newName;
std::map<std::string, Task *> tasks {
{"setName", new Task(retVal, &Square::setName, &newName)}
...
}
/* Modify the name however you want */
...
tasks["setname"]();
}
This whole class could be optimized, of course, primarily thanks to C++14 and move semantics, universal references and all, but I kept it simple ~
A major problem is that you have to use pointers if you don't know the values of the parameters at the time you fill the task map. I'm working on another version to simplify this aspect, but I wanted to show you that C++ is not designed to do what you ask simply. Maybe you come from a functional or JS world, in which this would be trivial x)
Update 2
I just wanted to point out that with C++14, you could omit the first 3 structures that are here to help me expand my tuple in an argument list using interger_sequence

C++ function argument safety

In a function that takes several arguments of the same type, how can we guarantee that the caller doesn't mess up the ordering?
For example
void allocate_things(int num_buffers, int pages_per_buffer, int default_value ...
and later
// uhmm.. lets see which was which uhh..
allocate_things(40,22,80,...
A typical solution is to put the parameters in a structure, with named fields.
AllocateParams p;
p.num_buffers = 1;
p.pages_per_buffer = 10;
p.default_value = 93;
allocate_things(p);
You don't have to use fields, of course. You can use member functions or whatever you like.
If you have a C++11 compiler, you could use user-defined literals in combination with user-defined types. Here is a naive approach:
struct num_buffers_t {
constexpr num_buffers_t(int n) : n(n) {} // constexpr constructor requires C++14
int n;
};
struct pages_per_buffer_t {
constexpr pages_per_buffer_t(int n) : n(n) {}
int n;
};
constexpr num_buffers_t operator"" _buffers(unsigned long long int n) {
return num_buffers_t(n);
}
constexpr pages_per_buffer_t operator"" _pages_per_buffer(unsigned long long int n) {
return pages_per_buffer_t(n);
}
void allocate_things(num_buffers_t num_buffers, pages_per_buffer_t pages_per_buffer) {
// do stuff...
}
template <typename S, typename T>
void allocate_things(S, T) = delete; // forbid calling with other types, eg. integer literals
int main() {
// now we see which is which ...
allocate_things(40_buffers, 22_pages_per_buffer);
// the following does not compile (see the 'deleted' function):
// allocate_things(40, 22);
// allocate_things(40, 22_pages_per_buffer);
// allocate_things(22_pages_per_buffer, 40_buffers);
}
Two good answers so far, one more: another approach would be to try leverage the type system wherever possible, and to create strong typedefs. For instance, using boost strong typedef (http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/strong_typedef.html).
BOOST_STRONG_TYPEDEF(int , num_buffers);
BOOST_STRONG_TYPEDEF(int , num_pages);
void func(num_buffers b, num_pages p);
Calling func with arguments in the wrong order would now be a compile error.
A couple of notes on this. First, boost's strong typedef is rather dated in its approach; you can do much nicer things with variadic CRTP and avoid macros completely. Second, obviously this introduces some overhead as you often have to explicitly convert. So generally you don't want to overuse it. It's really nice for things that come up over and over again in your library. Not so good for things that come up as a one off. So for instance, if you are writing a GPS library, you should have a strong double typedef for distances in metres, a strong int64 typedef for time past epoch in nanoseconds, and so on.
(Note: post was originally tagged 'C`)
C99 onwards allows an extension to #Dietrich Epp idea: compound literal
struct things {
int num_buffers;
int pages_per_buffer;
int default_value
};
allocate_things(struct things);
// Use a compound literal
allocate_things((struct things){.default_value=80, .num_buffers=40, .pages_per_buffer=22});
Could even pass the address of the structure.
allocate_things(struct things *);
// Use a compound literal
allocate_things(&((struct things){.default_value=80,.num_buffers=40,.pages_per_buffer=22}));
You can't. That's why it is recommended to have as few function arguments as possible.
In your example you could have separate functions like set_num_buffers(int num_buffers), set_pages_per_buffer(int pages_per_buffer) etc.
You probably have noticed yourself that allocate_things is not a good name because it doesn't express what the function is actually doing. Especially I would not expect it to set a default value.
Just for completeness, you could use named arguments, when your call becomes.
void allocate_things(num_buffers=20, pages_per_buffer=40, default_value=20);
// or equivalently
void allocate_things(pages_per_buffer=40, default_value=20, num_buffers=20);
However, with the current C++ this requires quite a bit of code to be implemented (in the header file declaring allocate_things(), which must also declare appropriate external objects num_buffers etc providing operator= which return a unique suitable object).
---------- working example (for sergej)
#include <iostream>
struct a_t { int x=0; a_t(int i): x(i){} };
struct b_t { int x=0; b_t(int i): x(i){} };
struct c_t { int x=0; c_t(int i): x(i){} };
// implement using all possible permutations of the arguments.
// for many more argumentes better use a varidadic template.
void func(a_t a, b_t b, c_t c)
{ std::cout<<"a="<<a.x<<" b="<<b.x<<" c="<<c.x<<std::endl; }
inline void func(b_t b, c_t c, a_t a) { func(a,b,c); }
inline void func(c_t c, a_t a, b_t b) { func(a,b,c); }
inline void func(a_t a, c_t c, b_t b) { func(a,b,c); }
inline void func(c_t c, b_t b, a_t a) { func(a,b,c); }
inline void func(b_t b, a_t a, c_t c) { func(a,b,c); }
struct make_a { a_t operator=(int i) { return {i}; } } a;
struct make_b { b_t operator=(int i) { return {i}; } } b;
struct make_c { c_t operator=(int i) { return {i}; } } c;
int main()
{
func(b=2, c=10, a=42);
}
Are you really going to try to QA all the combinations of arbitrary integers? And throw in all the checks for negative/zero values etc?
Just create two enum types for minimum, medium and maximum number of buffers, and small medium and large buffer sizes. Then let the compiler do the work and let your QA folks take an afternoon off:
allocate_things(MINIMUM_BUFFER_CONFIGURATION, LARGE_BUFFER_SIZE, 42);
Then you only have to test a limited number of combinations and you'll have 100% coverage. The people working on your code 5 years from now will only need to know what they want to achieve and not have to guess the numbers they might need or which values have actually been tested in the field.
It does make the code slightly harder to extend, but it sounds like the parameters are for low-level performance tuning, so twiddling the values should not be perceived as cheap/trivial/not needing thorough testing. A code review of a change from
allocate_something(25, 25, 25);
...to
allocate_something(30, 80, 42);
...will likely get just a shrug/blown off, but a code review of a new enum value EXTRA_LARGE_BUFFERS will likely trigger all the right discussions about memory use, documentation, performance testing etc.

C++ similar behavior to java.lang.Enum<E> [duplicate]

It is common knowledge that built-in enums in C++ are not typesafe.
I was wondering which classes implementing typesafe enums are used out there...
I myself use the following "bicycle", but it is somewhat verbose and limited:
typesafeenum.h:
struct TypesafeEnum
{
// Construction:
public:
TypesafeEnum(): id (next_id++), name("") {}
TypesafeEnum(const std::string& n): id(next_id++), name(n) {}
// Operations:
public:
bool operator == (const TypesafeEnum& right) const;
bool operator != (const TypesafeEnum& right) const;
bool operator < (const TypesafeEnum& right) const;
std::string to_string() const { return name; }
// Implementation:
private:
static int next_id;
int id;
std::string name;
};
typesafeenum.cpp:
int TypesafeEnum::next_id = 1;
bool TypesafeEnum::operator== (const TypesafeEnum& right) const
{ return id == right.id; }
bool TypesafeEnum::operator!= (const TypesafeEnum& right) const
{ return !operator== (right); }
bool TypesafeEnum::operator< (const TypesafeEnum& right) const
{ return id < right.id; }
Usage:
class Dialog
{
...
struct Result: public TypesafeEnum
{
static const Result CANCEL("Cancel");
static const Result OK("Ok");
};
Result doModal();
...
};
const Dialog::Result Dialog::Result::OK;
const Dialog::Result Dialog::Result::CANCEL;
Addition:
I think I should have been more specific about the requirements. I'll try to summarize them:
Priority 1: Setting an enum variable to an invalid value should be impossible (a compile-time error) with no exceptions.
Priority 2: Converting an enum value to/from an int should be possible with a single explicit function/method call.
Priority 3: As compact, elegant and convenient declaration and usage as possible
Priority 4: Converting enum values to and from strings.
Priority 5: (Nice to have) Possibility to iterate over enum values.
I'm currently playing around with the Boost.Enum proposal from the Boost Vault (filename enum_rev4.6.zip). Although it was never officially submitted for inclusion into Boost, it's useable as-is. (Documentation is lacking but is made up for by clear source code and good tests.)
Boost.Enum lets you declare an enum like this:
BOOST_ENUM_VALUES(Level, const char*,
(Abort)("unrecoverable problem")
(Error)("recoverable problem")
(Alert)("unexpected behavior")
(Info) ("expected behavior")
(Trace)("normal flow of execution")
(Debug)("detailed object state listings")
)
And have it automatically expand to this:
class Level : public boost::detail::enum_base<Level, string>
{
public:
enum domain
{
Abort,
Error,
Alert,
Info,
Trace,
Debug,
};
BOOST_STATIC_CONSTANT(index_type, size = 6);
Level() {}
Level(domain index) : boost::detail::enum_base<Level, string>(index) {}
typedef boost::optional<Level> optional;
static optional get_by_name(const char* str)
{
if(strcmp(str, "Abort") == 0) return optional(Abort);
if(strcmp(str, "Error") == 0) return optional(Error);
if(strcmp(str, "Alert") == 0) return optional(Alert);
if(strcmp(str, "Info") == 0) return optional(Info);
if(strcmp(str, "Trace") == 0) return optional(Trace);
if(strcmp(str, "Debug") == 0) return optional(Debug);
return optional();
}
private:
friend class boost::detail::enum_base<Level, string>;
static const char* names(domain index)
{
switch(index)
{
case Abort: return "Abort";
case Error: return "Error";
case Alert: return "Alert";
case Info: return "Info";
case Trace: return "Trace";
case Debug: return "Debug";
default: return NULL;
}
}
typedef boost::optional<value_type> optional_value;
static optional_value values(domain index)
{
switch(index)
{
case Abort: return optional_value("unrecoverable problem");
case Error: return optional_value("recoverable problem");
case Alert: return optional_value("unexpected behavior");
case Info: return optional_value("expected behavior");
case Trace: return optional_value("normal flow of execution");
case Debug: return optional_value("detailed object state listings");
default: return optional_value();
}
}
};
It satisfies all five of the priorities which you list.
A nice compromise method is this:
struct Flintstones {
enum E {
Fred,
Barney,
Wilma
};
};
Flintstones::E fred = Flintstones::Fred;
Flintstones::E barney = Flintstones::Barney;
It's not typesafe in the same sense that your version is, but the usage is nicer than standard enums, and you can still take advantage of integer conversion when you need it.
I use C++0x typesafe enums. I use some helper template/macros that provide the to/from string functionality.
enum class Result { Ok, Cancel};
I don't. Way too much overhead for little benefit. Also, being able to caste enumerations to different data types for serialization is a very handy tool. I have never seen an instance where a "Type safe" enumeration would be worth the overhead and complexity where C++ offers a good enough implementation already.
My take is that you're inventing a problem and then fitting a solution onto it. I see no need to do an elaborate framework for an enumeration of values. If you are dedicated to having your values only be members of a certain set, you could hack up a variant of a unique set datatype.
I'm personally using an adapted version of the typesafe enum idiom. It doesn't provide all the five "requirements" that you've stated in your edit, but I strongly disagree with some of them anyway. For example, I don't see how Prio#4 (conversion of values to strings) has anything to do with type safety. Most of the time string representation of individual values should be separate from the definition of the type anyway (think i18n for a simple reason why). Prio#5 (iteratio, which is optional) is one of the nicest things I'd like to see naturally happening in enums, so I felt sad that it appears as "optional" in your request, but it seems it is better addressed via a separate iteration system such as begin/end functions or an enum_iterator, which makes them work seamlessly with STL and C++11 foreach.
OTOH this simple idiom nicely provides Prio#3 Prio#1 thanks to the fact that it mostly only wraps enums with more type information. Not to mention it is a very simple solution that for the most part doesn't require any external dependency headers, so it's pretty easy to carry around. It also has the advantage of making enumerations scoped a-la-C++11:
// This doesn't compile, and if it did it wouldn't work anyway
enum colors { salmon, .... };
enum fishes { salmon, .... };
// This, however, works seamlessly.
struct colors_def { enum type { salmon, .... }; };
struct fishes_def { enum type { salmon, .... }; };
typedef typesafe_enum<colors_def> colors;
typedef typesafe_enum<fishes_def> fishes;
The only "hole" that solution provides is that it doesn't address the fact that it doesn't prevent enums of different types (or an enum and an int) from being directly compared, because when you use values directly you force the implicit conversion to int:
if (colors::salmon == fishes::salmon) { .../* Ooops! */... }
But so far I've found such problems can be solved by simply offering a better comparison to the compiler - for example, explicitly providing an operator that compares any two different enum types, then forcing it to fail:
// I'm using backports of C++11 utilities like static_assert and enable_if
template <typename Enum1, typename Enum2>
typename enable_if< (is_enum<Enum1>::value && is_enum<Enum2>::value) && (false == is_same<Enum1,Enum2>::value) , bool >
::type operator== (Enum1, Enum2) {
static_assert (false, "Comparing enumerations of different types!");
}
Though it doesn't seem to break code so far, and it does to explicitly deal with the specific problem without doing something else, I'm not sure it such thing is a thing one "should" do (I suspect it will interfere with enums already taking part in conversion operators declared elsewhere; I'd gladly receive commentary about this).
Combining this with the above typesafe idiom gives something that is relatively close to C++11 enum class in humanibility (readability and maintainability) without having to do anything too obscure. And I have to admit it was fun to do, I had never thought to actually ask the compiler if I was dealing with enums or not...
I think the Java enum would be a good model to follow. Essentially, the Java form would look like this:
public enum Result {
OK("OK"), CANCEL("Cancel");
private final String name;
Result(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
What's interesting about the Java approach is that OK and CANCEL are immutable, singleton instances of Result (with the methods that you see). You cannot create any further instances of Result. Since they're singletons, you can compare by pointer/reference---very handy. :-)
ETA: In Java, instead of doing bitmasks by hand, instead you use an EnumSet to specify a bit set (it implements the Set interface, and works like sets---but implemented using bitmasks). Much more readable than hand-written bitmask manipulation!
I gave an answer to this here, on a different topic. It's a different style of approach which allows most of the same functionality without requiring modification to the original enum definition (and consequently allowing usage in cases where you don't define the enum). It also allows runtime range checking.
The downside of my approach is that it doesn't programmatically enforce the coupling between the enum and the helper class, so they have to be updated in parallel. It works for me, but YMMV.
I am currently writing my own typesafe enum library at https://bitbucket.org/chopsii/typesafe-enums
I am not the most experienced C++ developer ever, but I am writing this due to the shortcomings of the BOOST vault enums.
Feel free to check it out and use them yourself, but they have some (hopefully minor) usability issues, and are probably not at all cross-platform.
Please contribute if you want to. This is my first open source undertaking.
Use boost::variant!
After trying a lot of the above ideas and finding them lacking I hit upon this simple approach:
#include <iostream>
#include <boost/variant.hpp>
struct A_t {};
static const A_t A = A_t();
template <typename T>
bool isA(const T & x) { if(boost::get<A_t>(&x)) return true; return false; }
struct B_t {};
static const B_t B = B_t();
template <typename T>
bool isB(const T & x) { if(boost::get<B_t>(&x)) return true; return false; }
struct C_t {};
static const C_t C = C_t();
template <typename T>
bool isC(const T & x) { if(boost::get<C_t>(&x)) return true; return false; }
typedef boost::variant<A_t, B_t> AB;
typedef boost::variant<B_t, C_t> BC;
void ab(const AB & e)
{
if(isA(e))
std::cerr << "A!" << std::endl;
if(isB(e))
std::cerr << "B!" << std::endl;
// ERROR:
// if(isC(e))
// std::cerr << "C!" << std::endl;
// ERROR:
// if(e == 0)
// std::cerr << "B!" << std::endl;
}
void bc(const BC & e)
{
// ERROR:
// if(isA(e))
// std::cerr << "A!" << std::endl;
if(isB(e))
std::cerr << "B!" << std::endl;
if(isC(e))
std::cerr << "C!" << std::endl;
}
int main() {
AB a;
a = A;
AB b;
b = B;
ab(a);
ab(b);
ab(A);
ab(B);
// ab(C); // ERROR
// bc(A); // ERROR
bc(B);
bc(C);
}
You can probably come up with a macro to generate the boilerplate. (Let me know if you do.)
Unlike other approaches this one is actually type-safe and works with old C++. You can even make cool types like boost::variant<int, A_t, B_t, boost::none>, for example, to represent a value that could be A, B, an integer or nothing which is almost Haskell98 levels of type safety.
Downsides to be aware of:
at-least with old boost -- I'm on a system with boost 1.33 -- you are limited to 20 items in your variant; there is a work-around however
affects compile time
insane error messages -- but that's C++ for you
Update
Here, for your convenience is your typesafe-enum "library". Paste this header:
#ifndef _TYPESAFE_ENUMS_H
#define _TYPESAFE_ENUMS_H
#include <string>
#include <boost/variant.hpp>
#define ITEM(NAME, VAL) \
struct NAME##_t { \
std::string toStr() const { return std::string( #NAME ); } \
int toInt() const { return VAL; } \
}; \
static const NAME##_t NAME = NAME##_t(); \
template <typename T> \
bool is##NAME(const T & x) { if(boost::get<NAME##_t>(&x)) return true; return false; } \
class toStr_visitor: public boost::static_visitor<std::string> {
public:
template<typename T>
std::string operator()(const T & a) const {
return a.toStr();
}
};
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
inline static
std::string toStr(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> & a) {
return boost::apply_visitor(toStr_visitor(), a);
}
class toInt_visitor: public boost::static_visitor<int> {
public:
template<typename T>
int operator()(const T & a) const {
return a.toInt();
}
};
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
inline static
int toInt(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> & a) {
return boost::apply_visitor(toInt_visitor(), a);
}
#define ENUM(...) \
typedef boost::variant<__VA_ARGS__>
#endif
And use it like:
ITEM(A, 0);
ITEM(B, 1);
ITEM(C, 2);
ENUM(A_t, B_t) AB;
ENUM(B_t, C_t) BC;
Notice you have to say A_t instead of A in the ENUM macro which destroys some of the magic. Oh well. Also, notice there's now a toStr function and a toInt function to meet OPs requirement of simple conversion to strings and ints. The requirement I can't figure out is a way to iterate over the items. Let me know if you know how to write such a thing.
Not sure if this post is too late, but there's an article on GameDev.net which satisfies all but the 5th point (ability to iterate over enumerators):
http://www.gamedev.net/reference/snippets/features/cppstringizing/
The method described by the article allows string conversion support for existing enumerations without changing their code. If you only want support for new enumerations though, I'd go with Boost.Enum (mentioned above).

choose correct template specialization at run-time

I have
template <int i> struct a { static void f (); };
with specializations done at different places in the code. How can I call the correct a<i>::f for an i known only at runtime?
void f (int i) { a<i>::f (); } // won't compile
I don't want to list all possible values of i in a big switch.
Edit:
I thought of something like
#include <iostream>
template <int i> struct a { static void f (); };
struct regf {
typedef void (*F)();
enum { arrsize = 10 };
static F v[arrsize];
template < int i > static int apply (F f) {
static_assert (i < arrsize, "");
v[i] = a<i>::f;
return 0;
}
};
regf::F regf::v[arrsize];
template <int i> struct reg { static int dummy; };
template <int i> int reg<i>::dummy = regf::apply<i> ();
void f (int i) { return regf::v[i] (); }
#define add(i) \
template <> struct a<i> : reg<i> { \
static void f () { std::cout << i << "\n"; } \
};
add(1)
add(3)
add(5)
add(7)
int main () {
f (3);
f (5);
}
but it crashes (did I miss something to force an instantiation?), and I don't like that dummy is not static const (and uses memory) and of course that arrsize is bigger than necessary.
Actual problem: To have a function generate (int i) that calls a<i>::generate () to generate an instance of class a<i> for an i given only at run-time. The design (classes a<i>) is given, they inherit from a base class and more specializations of a could be added at any time anywhere in the code, but I don't want to force everyone to change my generate (i) manually as that could be forgotten easily.
I am not sure that this is the best solution that you can get, as there might be better designs, at any rate you can use some metaprogramming to trigger the instantiation and registry of the functions:
// in a single cpp file
namespace {
template <unsigned int N>
int register_a() { // return artificially added
register_a<N-1>(); // Initialize array from 0 to N-1
regf::v[N] = &a<N>::f; // and then N
return N;
}
template <>
int register_a<0>() {
regf::v[0] = &a<0>::f; // recursion stop condition
return 0;
}
const int ignored = register_a<regf::arrsize>(); // call it
}
That code will instantiate the functions and register pointers to the static member functions. The fake return type is required to be able to force execution of the function in an static context (by means of using that function to initialize a static value).
This is quite prone to the static initialization fiasco. While regf::v is ok, any code that depends on regf::v containing the appropriate pointers during static initialization is bound to fail. You can improve this with the usual techniques...
From the bits and pieces that you have actually posted, my guess is that you are trying to use an abstract factory with automated registration from each one of the concrete factories. There are better ways of approaching the problem, but I think that this answer solves your question (I am unsure on whether this does solve your problem).
You have to. Templates are resolved and instantiated at compile-time. Apart from that, a switch needn't be inefficient. It usually compiles to a lookup table with very little overhead.
You can, however, use recursive template magic to have nested if/else blocks to replace the switch generated for you by the compiler. But a plain switch should be much more readable. Unless of course you have literally thousands of cases.
In either case, you need to know the set of values that i can have at compilation time since the compiler needs to know which templates to instantiate.
You can't pick a template specialization at runtime, they're by definition chosen at compile time.
The usual ways to solve the dispatch problem you're looking at are switch (as you surmised) or a vector or map of int to function pointer.
No, compiler needs to the instantiation of the template at compile time, for that it needs to know the value of i at compile time.
You can't as template instantiation is done at compile time.