Veaviticus
Veaviticus

Reputation: 293

Initialization list for vector of function pointers in c++11

I'm attempting to codify a DFA using a table of function pointers.

The table is populated by function pointers to functions to either output something or move to another state in the table, all based off what input the machine receives.

Right now what I can do is

function<token* ()> A1 = bind(A, &data);
function<token* ()> A2 = bind(B, &data);
function<token* ()> S1 = bind(S, 1);
function<token* ()> S2 = bind(S, 2);

vector< function<token* ()> > _table = { A1, A2, S1, S2 };

To make a 2x2 "table" where [0][0] performs action A1, [0][1] performs actions A2, [1][0] does shift to row 1, [1][1] does a shift to row 2... and so on.

My question is, in c++11, is there any faster way to do this? My state table has grown to 60x150, I have 50 different actions all bound to different functions, and I have to define a shift function to get to each row.

I'm trying to do this all in C++11's initialization features so it is done at compile time rather than at run time.

Is it possible to create a macro or something that performs something like:

vector<function<token* ()> > S;
for(int i = 0; i < 60; i++){
  function<token* ()> S[i] = bind(S, i);
}

so that after that I can reference S[3] or whatever and it gives me back the appropriately bound function pointer?

Upvotes: 1

Views: 651

Answers (1)

Jesse Good
Jesse Good

Reputation: 52365

Using Boost Preprocessor you can make some easily:

For example:

#include <vector>
#include <functional>
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
struct token{};
token* S(int){return new token;}
#define MAKE_FUNCT(z, n, unused)         \
BOOST_PP_COMMA_IF(n)                     \
std::bind(S, n)                          \

int main()
{
   std::vector<std::function<token* ()>> table = 
                  {BOOST_PP_REPEAT(10, MAKE_FUNCT, ~)};
}

Here is an example, passing the -E flag I get:

std::vector<std::function<token* ()>> table = { std::bind(S, 0) , std::bind(S, 1) , std::bind(S, 2) , std::bind(S, 3) , std::bind(S, 4) , std::bind(S, 5) , std::bind(S, 6) , std::bind(S, 7) , std::bind(S, 8) , std::bind(S, 9)};

Upvotes: 1

Related Questions