|
Boost : |
From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2007-11-27 10:49:52
After few months of inactivity I came back to a local function syntax. Instead
of trying to bind local variables, I implemented a couple of macros that simply
assign a value to a function pointer:
int BOOST_LOCAL_FUNCTION(char c)
{
std::cout << c << '\n';
return 1;
} BOOST_LOCAL_FUNCTION_DECL(a)
a('A');
// output:
// A
This code defines int (*a)(char) and assigns to it a pointer to the body of
local function shown above.
Half-preprocessed output is
int (*sig16)() = 0; typedef struct { static BOOST_TYPEOF(sig16()) body(char c)
{
std::cout << c << '\n';
return 1;
} } local20; BOOST_AUTO(a, &local20::body);
a('A');
It's also possible to assign a pointer to any object compartible with int (*)
(char):
boost::function<int(char)> zz;
int BOOST_LOCAL_FUNCTION(char c)
{
std::cout << c << c << '\n';
return 2;
} BOOST_LOCAL_FUNCTION_ASSIGN(zz)
zz('Z');
// output:
// ZZ
Proof of concept code is in the end of this message.
Currently, it doesn't handle void return (Boost.Typeof limitation) and doesn't
compile when arguments or return type is a dependant name. gcc 3.4 often
crashes on local function defined inside templates.
#include <iostream>
#include <boost/function.hpp>
#include <boost/typeof/typeof.hpp>
#define BOOST_LOCAL_FUNCTION (*BOOST_PP_CAT(sig,__LINE__))() = 0; \
typedef struct { static BOOST_TYPEOF(BOOST_PP_CAT(sig,__LINE__)()) body
#define BOOST_LOCAL_FUNCTION_ASSIGN(f) } BOOST_PP_CAT(local,__LINE__); \
f = &BOOST_PP_CAT(local,__LINE__)::body;
#define BOOST_LOCAL_FUNCTION_DECL(f) } BOOST_PP_CAT(local,__LINE__); \
BOOST_AUTO(f, &BOOST_PP_CAT(local,__LINE__)::body);
int main()
{
int BOOST_LOCAL_FUNCTION(char c)
{
std::cout << c << '\n';
return 1;
} BOOST_LOCAL_FUNCTION_DECL(a)
a('A');
boost::function<int(char)> zz;
int BOOST_LOCAL_FUNCTION(char c)
{
std::cout << c << c << '\n';
return 2;
} BOOST_LOCAL_FUNCTION_ASSIGN(zz)
zz('Z');
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk