Boost logo

Boost :

From: Peder Holt (peder.holt_at_[hidden])
Date: 2004-08-28 17:07:18

On Sat, 28 Aug 2004 12:47:23 +0100, Daniel James <daniel_at_[hidden]> wrote:
> I've come up with an alternative way to invoke the typeof emulations
> that have been posted. It basically works by defining an iterator over
> the encoded type. Unfortunately, it can't be used inside a function, and
> is awkward to use in general, but has the advantage is that it only has
> to define the call to foo once, which might result in faster compile times.
> It could possibly also remove the limit on the complexity of the type.
> Arkadiy's version would require a some changes to do this, but I think
> Peder's could quite easily. Although I'm not sure as I've only had a
> brief look at his version.
> I've implemented it as a sort of typedef, which seems like the easiest
> way to use it.
> It's probably easier to understand the code than my explanation, so here
> it is. It's based on Arkadiy's version in the yahoo groups file section.
> template <int pos> \
> struct iterator { \
> typedef boost::mpl::int_< \
> sizeof(boost::type_of::foo<pos>(Expr))> type; \
> typedef iterator<pos+1> next; \
> }; \
> };
> #define BOOST_TYPEOF_TYPEDEF(Expr, Name) \
> typedef boost::type_of::decode_type< \
> >::type Name;
> #define BOOST_TYPEOF_TPL_TYPEDEF(Expr, Name) \
> typedef typename boost::type_of::decode_type< \
> >::type Name;
> Here is an example of it's use:
> template <class Op>
> struct result_of_nullary_functor
> {
> static Op op;
> };
> struct g { int operator()(); };
> BOOST_MPL_ASSERT_IS_SAME(result_of_nullary_functor<g>::type, int);

I like the idea, and it is compatible with the first version of
typedef that I implemented. In this version, a function returns the
size of element # N in a sequence:
The problem with this expression, is that because of the lack of
partial template specialization, you have to use functions to deduce
the type of an expression, and you have to use sizeof for every step
in order to get something sensible out of the function expression:
Typically, to deduce a pointer expression, you have to do something like:
            template<typename U>
            static typename
sizer<encode_indirection<Level-1,U,Types>::value>::type encode(U const
            BOOST_STATIC_CONSTANT(unsigned,value=sizeof( encode((T)NULL) ));
The compiler did not like deep nesting of sizeof calls. This caused
the compiler to complain after 9 or 10 levels.

The solution was to roll out the nesting, so now I have functions
returning function pointers:

template<typename T,typename Types>
typename modifiers<T,Types>::type foo(void (*)(sizer<CV_POINTER>,T
const volatile*,Types));

where modifiers<T,Types> deduces the proper function pointer to decode T.
In this way, foo(foo(foo_start(expr))) points to the 3'rd element in
the expression.
I have tested this approach with an expression with the depth 120 and
BOOST_MAX_TYPEOF_SIZE 150 (with mindboggingly slow compilation times)
and it managed to deduce its type correctly.
The problem of my current implementation, is that this is an N^2 process:
value_type<sizeof(foo_start(expr)), //Level 1
value_type<sizeof(foo(foo_start(expr))),//Level 2
value_type<sizeof(foo(foo(foo_start(expr)))),Level 3
> > >
What would be very nice (but probably unattainable) was to reduce this
into an N process. Any suggestions would be most welcome.

Peder Holt
> I've only tested on the intel linux compiler.
> Daniel
> _______________________________________________
> Unsubscribe & other changes:

Boost list run by bdawes at, gregod at, cpdaniel at, john at