Boost logo

Boost :

From: Peder Holt (peder.holt_at_[hidden])
Date: 2004-08-27 14:16:55


On Fri, 27 Aug 2004 02:00:35 -0400, Arkadiy Vertleyb
<vertleyb_at_[hidden]> wrote:
> "Paul Mensonides" <pmenso57_at_[hidden]> wrote
>
> > It isn't usually the case that preprocessor metaprogramming is used to do
> type
> > computation. It is possible, of course, given enough scaffolding, but
> templates
> > are much more naturally suited to it. Types as values just doesn't scale
> with
> > the preprocessor. It is common, OTOH, to generate a template-based
> solution
> > with the preprocessor. Thus, what exactly are you trying to do?
>
> I am trying to extend my typeof emulation system (see
> http://groups.yahoo.com/group/boost/files/typeof.zip) with the ability to
> conveniently support integral template parameters. I am generating partial
> template specializations that are responsible for encoding/decoding of a
> template instantiation. In such specialization, type parameters are handled
> differently from integral parameters in a few different aspects. I could
> encapsulate these aspects in a preprocessor tuple, and provide macros to
> generate these tuples, so that I would get something like this from the
> user:
>
> template<typename T, bool b, unsigned int n> class foo;
>
> REGISTER_TEMPLATE(foo, 3, (
> TYPE_ARG,
> INTEGRAL_ARG(bool),
> INTEGRAL_ARG(unsigned int)
> )); // this expands into encoding/decoding specializations
>
> Here both TYPE_ARG and INTEGRAL_ARG(x) expand into a preprocessor tuple
> where all the necessary information is contained, so that I can generate my
> specializations.
>
> This looks implementable, but I am just trying to explore an alternative,
> where the user would just specify:
>
> REGISTER_TEMPLATE(foo, 3, (typename, bool, unsigned int));
>
> And this requires to associate a few properties with, e.g., "unsigned int",
> which caused my original question.
>
> > > So I am wonderring if there is any facility in the
> > > preprocessor (or in the
> > > Boost.Preprocessor) that would allow me to do this.
> >
> > There isn't a facility to do it directly in the pp-lib, but it is
> possible.
>
> Any information on the subject would be greatly appreciated.
>
> Thanks,
> Arkadiy

I solved this version in the vintage version of typeof.

I ended up defining three macros for encoding and three macros for decoding:
(probably only need 2)

//encoding classes
#define BOOST_TYPEOF_typename_encode(arg) arg
#define BOOST_TYPEOF_integral_encode(arg) integral_wrapper<arg> BOOST_PP_EMPTY()
#define BOOST_TYPEOF_unsigned_integral_encode(arg)
unsigned_integral_wrapper<arg> BOOST_PP_EMPTY()

//Decoding templates
#define BOOST_TYPEOF_typename_decode(n,text) ...
#define BOOST_TYPEOF_integral_decode(n,text) ...
#define BOOST_TYPEOF_unsigned_integral_decode(n,text) ...

Use BOOST_TYPEOF_DECODE_ARGUMENT to create the correct decode macro,
and BOOST_TYPEOF_ENCODE_ARGUMENT to encode it.

Here is the source:

// Copyright (C) 2004 Peder Holt
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_TYPEOF_TYPE_TO_MACRO_HPP_HOLT_2004_0827
#define BOOST_TYPEOF_TYPE_TO_MACRO_HPP_HOLT_2004_0827

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/paren.hpp>

/*
These macros are used to dechifer template arguments into sensible macros.
There are three predefined macro builders:
BOOST_TYPEOF_typename - for class and typename arguments
BOOST_TYPEOF_integral - for signed integral values, int,short,char,bool, etc.
BOOST_TYPEOF_unsigned_integral - for unsigned integral values,
unsigned, unsigned long etc.

All the fundamental integral types (except long long) have been pre-registered.
In order to implement new template argument types (enums),
you need to define a macro containing the name of the enum:

enum MyEnum {red=0,green=1,blue=2};
#define BOOST_TYPEOF__MyEnum__ BOOST_TYPEOF_integral

//MyEnum is now treated as an integral value in template expressions.

template<MyEnum value>
struct enum_class {};

//Is registered using
BOOST_TYPEOF_DEFINE_TEMPLATE(enum_class,1,(MyEnum))
*/

#define BOOST_TYPEOF_typename(dummy,append,arg)
BOOST_PP_CAT(BOOST_TYPEOF_typename_,append)arg
#define BOOST_TYPEOF_integral(dummy,append,arg)
BOOST_PP_CAT(BOOST_TYPEOF_integral_,append)arg
#define BOOST_TYPEOF_unsigned_integral(dummy,append,arg)
BOOST_PP_CAT(BOOST_TYPEOF_unsigned_integral_,append)arg

#define BOOST_TYPEOF__typename__ BOOST_TYPEOF_typename(dummy
#define BOOST_TYPEOF__class__ BOOST_TYPEOF_typename(dummy
#define BOOST_TYPEOF__bool__ BOOST_TYPEOF_integral(dummy
#define BOOST_TYPEOF__char__ BOOST_TYPEOF_integral(dummy
#define BOOST_TYPEOF__short__ BOOST_TYPEOF_integral(dummy
#define BOOST_TYPEOF__int__ BOOST_TYPEOF_integral(dummy
#define BOOST_TYPEOF__long__ BOOST_TYPEOF_integral(dummy
#define BOOST_TYPEOF__unsigned__ BOOST_TYPEOF_unsigned_integral(dummy
#define BOOST_TYPEOF__signed__ BOOST_TYPEOF_integral(dummy
#define BOOST_TYPEOF__unsigned BOOST_TYPEOF_unsigned_integral(
#define BOOST_TYPEOF__signed BOOST_TYPEOF_integral(

#define BOOST_TYPEOF_ENCODE_ARGUMENT(z,n,text)\
  BOOST_PP_CAT(BOOST_TYPEOF__,BOOST_PP_CAT(text,__)),encode,(BOOST_PP_CAT(A,n))
BOOST_PP_RPAREN()

#define BOOST_TYPEOF_ENCODE_ARRAY_ELEMENT(z,n,array)\
  BOOST_TYPEOF_ENCODE_ARGUMENT(z,n,BOOST_PP_ARRAY_ELEM(n, array))

#define BOOST_TYPEOF_DECODE_ARGUMENT(z,n,text)\
  BOOST_PP_CAT(BOOST_TYPEOF__,BOOST_PP_CAT(text,__)),decode,(n,text)
BOOST_PP_RPAREN()

#define BOOST_TYPEOF_DECODE_ARRAY_ELEMENT(z,n,array)\
  BOOST_TYPEOF_DECODE_ARGUMENT(z,n,BOOST_PP_ARRAY_ELEM(n, array))

#endif //BOOST_TYPEOF_TYPE_TO_MACRO_HPP_HOLT_2004_0827

>
>
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


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