Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2001-05-20 08:53:48


 Vesa Karvonen wrote:
> I'm thinking of submitting a small CPP or C Pre Processor
> meta programming library into Boost. For this reason I have
> uploaded a trivial demo subset of the library into the Files
> section/Vault. You can find the files under the CPP folder.
> The rest of this message contains a motivated example of the
> use of a particular feature of the library.

Funny, I've been using something like this for about half a year too. First
time I saw a simple example of the technique in the Lambda library
(LL_REPEAT, IIRC), and extending it to handle self-referential situations
was trivial :). Actually, if you look at 'boost::mpl' library headers
(http://groups.yahoo.com/group/boost/files/mpl/mpl-apr-28-01.zip), you'll
find a few examples of the technique applied as well:

// from 'mpl/switch_on.hpp'

template<typename T, BOOST_MPL_ENUMERATE_DEFAULT_PARAMS(class C,
null_argument)>
struct switch_on
    : mpl::detail::switch_impl< T,
mpl::type_list<BOOST_MPL_ENUMERATE_PARAMS(C)> >::result_type
    {
    };

// from 'mpl/list/factory.hpp'

#define BOOST_MPL_LIST_FACTORY_SPEC(N)
\
template<>
\
struct list_factory_part1<N>
\
    {
\
    template<class Tag, BOOST_MPL_ENUMERATE_PARAMS(typename T)>
\
    struct part2
\
        {
\
        typedef BOOST_MPL_ENUMERATE_N(N
\
            , typename mpl::list_traits<Tag>::template make_node<T)
\
            , typename mpl::list_traits<Tag>::null_node BOOST_MPL_REPEAT_N(N
\
            , >::type) type;
\
        };
\
    };

BOOST_MPL_ENUMERATE_USER_MACROS(BOOST_MPL_, LIST_FACTORY_SPEC)

and a couple of others. The macros themselves are in the
'mpl/enumeration_macros.hpp' and 'mpl/basic_macros.hpp' headers. Two-part
naming of the enumerated macro ("BOOST_MPL_, LIST_FACTORY_SPEC") is a
(historical) implementation artifact, but the rest is more or less
equivalent to your BOOST_LST0 and BOOST_LST1 approach, except that the names
of these are much longer - BOOST_MPL_ENUMERATE_MACRO_CALLS and
BOOST_MPL_ENUMERATE_USER_MACROS respectively :). Well, actually there are
some differences in techniques, but IMO they are rather minor. I would like
to see both approaches merged into something simple and elegant that would
become an official boost library :).

****************
An aside note:

Besides 'boost::mpl', I've been using the technique a lot in other projects,
and I find it a really useful alternative to external code
generation/preprocessing. However, as others already mentioned, it has its
own problems, and the main source of those is that the technique is still
preprocessor-based. It would be really great to have the language to support
compile-time type lists in template parameters and function signatures, so
instead of

template<typename R, ENUMERATE_ARGUMENTS_N(10, typename T)>
inline
function< R, ENUMERATE_ARGUMENTS_N(10, T) >
make_function(R (*f)( ENUMERATE_ARGUMENTS_N(10, T) ))
  {
  return function2<R, ENUMERATE_ARGUMENTS_N(10, T)>(f);
  }

one could write something like this:

template<typename R, typename[10] Ts>
inline
function< R, Ts>
make_function(R (*f)(Ts)
  {
  return function2<R, Ts>(f);
  }

Of course, something like the above requires a core language change (if
someone writes a proposal :), and that won't happen any time soon (if ever),
so IMO the discussed library has its place here.

Aleksey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk