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