|
Boost : |
From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2003-11-12 14:34:49
This is just an idea that I'm pondering in my mind, but maybe
someone finds it interesting. Consider the following template:
template<typename Functor>
struct executer
{
int operator()(int x){return f(x);}
private:
Functor f;
};
executer can be instantiated with any functor type just like
in the following example:
struct plus_one
{
int operator()(int x){return x+1;}
};
typedef executer<plus_one> my_executer;
Boost.Lambda is designed to save the user from writing these tiny
functors, so it'd be great if lambda exprs could be used in
template instantiations as well. Alas, this is not possible, for obvious
reasons:
typedef execute_function<lambda::_1*2> execute_doubling;
// KO: lambda::_1*2 is not a type
In order to get as close as this as possible, I've written
a proof of concept piece of code that allows the programmer
to write:
REGISTER_EXPRESSION(0,lambda::_1+1);
typedef executer<EXPRESSION_TYPE(0)> my_executer;
which is not as convenient as direct use of lambda, but it is more
comfortable than the non-assisted way. Incidentally, the macros
can be used to "typefy" regular functions:
int foo(int){...}
REGISTER_EXPRESSION(0,&foo);
typedef executer<EXPRESSION_TYPE(0)> my_executer;
Please find below a piece of code implementing the idea. This is only
the implementation of an idea, and as such it's got plenty of room for
improvement, but I thought the concepts underlying the technique could
be
of interest to Boosters.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
***BEGIN CODE***
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <map>
#include <string>
#include <iostream>
using namespace boost;
using namespace std;
// Code intended only for expressions accepting an int and returning an
int
typedef function1<int,int> mapped_function_t;
namespace{
map<int,mapped_function_t> entry_map;
}
template <int Entry> int mapped_function(int x)
{
static mapped_function_t f=entry_map[Entry];
return f(x);
}
template<int Entry>
struct function_type
{
int operator()(int x){return mapped_function<Entry>(x);}
};
#define REGISTER_EXPRESSION(entry,expr) entry_map[(entry)]=(expr);
#define EXPRESSION_TYPE(entry) function_type<(entry)>
template<typename Functor>
struct executer
{
int operator()(int x){return f(x);}
private:
Functor f;
};
int main()
{
REGISTER_EXPRESSION(0,lambda::_1+1);
REGISTER_EXPRESSION(1,lambda::_1*5);
cout<<executer<EXPRESSION_TYPE(0)>()(1)<<endl;
cout<<executer<EXPRESSION_TYPE(1)>()(1)<<endl;
return 0;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk