Boost logo

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