Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-11 Thread Paul Mensonides
- Original Message -
From: "David Abrahams" <[EMAIL PROTECTED]>

...

> I mean that if a metafunction is a template instead of a type you
> can't treat it polymorphically with other things, e.g. you can't put
> it in a type sequence.

Yes, you can with the appropriate binders.  That is what I meant.

> > struct metafunction {
> > template struct actual_metafunction {
> > // ...
> > };
> > };
> >
> > vs.
> >
> > template struct metafunction {
> > // ...
> > };
>
> mpl::lambda handles the transformation from the latter to the former.

Yeah, I retract that statement. ;)  It is easy to map them back and forth.

> > I'm not saying the convention is bad, just that it has its own set of
> > associated problems.
> >
> >> Other than that, the final interface you show is one that's acheivable
> >> without TTP at all.
> >
> > Yes, you can do it without TTP, but it isn't as clean.  (I only had a
rough
> > idea in my head when I made the remark.)  You pay a price for the
> > abstraction that you mention by "metafunction polymorphism."
>
> Hmm?

Code clarity.  As abstraction goes up, clarity goes down.

> > Altogether, I'm quite pleased with the mechanism, as I find the linear
> > typelist implementation "neat," and I've never seen anything like that
> > implementation.
>
> libs/python/test/if_else.cpp might be of interest to you.

I'll take a look.

> > The template classes "fold_left" and "fold_right" are not
> > even metafunctions in any normal sense.  I wouldn't know what to call
them!
>
> They're interesting to a point, but inflexible.  Any given usage is
> restricted to working on sequences of a particular length.

Yes, however, the intended purpose is as an inline definition, not as a
sequence type, and it doesn't require the code replication necessary to
support something like "mpl::vector".  I'm not saying that it's "super
great" overall.  I'm merely saying that it amuses me, and I like it. ;)

Paul Mensonides

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



Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-11 Thread David Abrahams
"Paul Mensonides" <[EMAIL PROTECTED]> writes:

> - Original Message -
> From: "David Abrahams" <[EMAIL PROTECTED]>
>
>> 
>>
>> AFAICT from browsing it quickly, the significance of TTP in your code
>> is that you are passing templates instead of types as functions in the
>> interfaces to your metafunctions, which I think is inadvisable,
>> because it eventually breaks metafunction polymorphism.
>
> Not really.  That is the purpose of various types of partial binding
> constructs.  The only real way to break metafunction polymorphism is to use
> non-type template arguments in the the template template parameters, and not
> even that will totally break it.  

I mean that if a metafunction is a template instead of a type you
can't treat it polymorphically with other things, e.g. you can't put
it in a type sequence.

> Strictly not using template template parameters has its own problems
> since you can't pass namespaces as arguments, etc..  This can
> complicate a design real quick as you make more and more
> "indirection" layers:
>
> struct metafunction {
> template struct actual_metafunction {
> // ...
> };
> };
>
> vs.
>
> template struct metafunction {
> // ...
> };

mpl::lambda handles the transformation from the latter to the former.

> I'm not saying the convention is bad, just that it has its own set of
> associated problems.
>
>> Other than that, the final interface you show is one that's acheivable
>> without TTP at all.
>
> Yes, you can do it without TTP, but it isn't as clean.  (I only had a rough
> idea in my head when I made the remark.)  You pay a price for the
> abstraction that you mention by "metafunction polymorphism."  

Hmm?

> The difference is that I prefer to do that abstraction external to
> the core implementation and provide a bridge layer for common
> usages.  In any case, it turns out to be slightly longer anyway
> because I forgot about the need for ::template when one (or all) of
> the parameters a dependent.  

Yes, the language syntax gets in the way.

> However, I was going for a general purpose "iterative OR" when I
> started it, rather than just a solution to the particular problem.
> I basically just had a general idea of something like this:
>
> contains::arg::arg::arg::value
>
> ...but the "::template" makes it longer:
>
> contains
> ::template arg
> ::template arg
> ::template arg
> ::value
>
> Altogether, I'm quite pleased with the mechanism, as I find the linear
> typelist implementation "neat," and I've never seen anything like that
> implementation.  

libs/python/test/if_else.cpp might be of interest to you.

> The template classes "fold_left" and "fold_right" are not
> even metafunctions in any normal sense.  I wouldn't know what to call them!

They're interesting to a point, but inflexible.  Any given usage is
restricted to working on sequences of a particular length.

-- 
   David Abrahams
   [EMAIL PROTECTED] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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



Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-10 Thread Paul Mensonides
- Original Message -
From: "David Abrahams" <[EMAIL PROTECTED]>

> 
>
> AFAICT from browsing it quickly, the significance of TTP in your code
> is that you are passing templates instead of types as functions in the
> interfaces to your metafunctions, which I think is inadvisable,
> because it eventually breaks metafunction polymorphism.

Not really.  That is the purpose of various types of partial binding
constructs.  The only real way to break metafunction polymorphism is to use
non-type template arguments in the the template template parameters, and not
even that will totally break it.  Strictly not using template template
parameters has its own problems since you can't pass namespaces as
arguments, etc..  This can complicate a design real quick as you make more
and more "indirection" layers:

struct metafunction {
template struct actual_metafunction {
// ...
};
};

vs.

template struct metafunction {
// ...
};

I'm not saying the convention is bad, just that it has its own set of
associated problems.

> Other than that, the final interface you show is one that's acheivable
> without TTP at all.

Yes, you can do it without TTP, but it isn't as clean.  (I only had a rough
idea in my head when I made the remark.)  You pay a price for the
abstraction that you mention by "metafunction polymorphism."  The difference
is that I prefer to do that abstraction external to the core implementation
and provide a bridge layer for common usages.  In any case, it turns out to
be slightly longer anyway because I forgot about the need for ::template
when one (or all) of the parameters a dependent.  However, I was going for a
general purpose "iterative OR" when I started it, rather than just a
solution to the particular problem.  I basically just had a general idea of
something like this:

contains::arg::arg::arg::value

...but the "::template" makes it longer:

contains
::template arg
::template arg
::template arg
::value

Altogether, I'm quite pleased with the mechanism, as I find the linear
typelist implementation "neat," and I've never seen anything like that
implementation.  The template classes "fold_left" and "fold_right" are not
even metafunctions in any normal sense.  I wouldn't know what to call them!

Paul Mensonides

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



Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-10 Thread David Abrahams
"Paul Mensonides" <[EMAIL PROTECTED]> writes:

> - Original Message -
> From: "David Abrahams" <[EMAIL PROTECTED]>
>
>> "Paul Mensonides" <[EMAIL PROTECTED]> writes:
>>
>> > Which could be even shorter yet if we could get away with template
>> > template parameters.
>>
>> We can and do.
>>
>> How would you imagine it would be spelled with TTP?
>
> You asked for it. ;)  Beware, this is the work of a sick mind!
> Basically, this implementation reduces the sample to an inline fold of the
> form:
>
> operation::step::step::step::[ value | type ]
>
> ...where 'operation' is the type of operation and where '[ value | type ]'
> is either 'value' or 'type'.
> Ultimately, we get something similar to this (with the help of a macro to
> handle the ::template that is sometimes necessary):
>
> is_present
> item 
> item 
> item 
> item 
> ::value
>



AFAICT from browsing it quickly, the significance of TTP in your code
is that you are passing templates instead of types as functions in the
interfaces to your metafunctions, which I think is inadvisable,
because it eventually breaks metafunction polymorphism.

Other than that, the final interface you show is one that's acheivable
without TTP at all.

-- 
   David Abrahams
   [EMAIL PROTECTED] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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



Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-09 Thread Paul Mensonides
- Original Message -
From: "David Abrahams" <[EMAIL PROTECTED]>

> "Paul Mensonides" <[EMAIL PROTECTED]> writes:
>
> > Which could be even shorter yet if we could get away with template
> > template parameters.
>
> We can and do.
>
> How would you imagine it would be spelled with TTP?

You asked for it. ;)  Beware, this is the work of a sick mind!
Basically, this implementation reduces the sample to an inline fold of the
form:

operation::step::step::step::[ value | type ]

...where 'operation' is the type of operation and where '[ value | type ]'
is either 'value' or 'type'.
Ultimately, we get something similar to this (with the help of a macro to
handle the ::template that is sometimes necessary):

is_present
item 
item 
item 
item 
::value

Also, the same underlying implementation is used to build
a completely linearized typelist mechanism:

typedef gen_typelist
item 
item 
item 
item 
item 
item 
item 
item 
item 
::type integral_types;

Here is the implementation (from scratch):

// identity:  yields its template argument as a typedef

template struct identity {
typedef T type;
};

// map_integral:  everyone's favorite plus a typedef
//representing the type of its stored value
//(this is just a hack because I was too lazy to detect it,
//and you can't do it with partial specialization because
//of the dependent second parameter.)

template struct map_integral : identity {
static const T value = V;
};

template const T map_integral::value;

// has_member_value:  metafunction that returns
// true if its template argument has a nested value
// named 'value'

template struct has_member_value {
private:
template struct helper;
template static char check(helper*);
template static char (& check(...))[2];
public:
static const bool value = sizeof(check(0)) == 1;
};

template const bool has_member_value::value;

namespace detail {

// fold_nil:  placeholder for "no previous state"
// it is used by fold_right

struct fold_nil;

// fold_helper:  the opposite of fold_nil
// it stores state needed for fold_right to reverse
// its the element order and use fold_left

template struct fold_helper { };

// fold_reversal:  metafunction that participates in
// building a reversed "list" of elements.

template struct fold_reversal;

// specialization for "no previous state"

template struct fold_reversal {
typedef build type;
};

// specialization otherwise

template
struct fold_reversal > {
typedef typename fold_reversal<
typename build::template step, parent
>::type type;
};

// value_if:  yields a nested static constant if 'T' has
// a 'value' member.  If so, 'T' must also have a member 'type'
// that denotes the 'type' of the static constant.
// This can be deduced, but I didn't feel like bothering to
// do it here.  (This is the reason that map_integral above has
// a 'type' typedef.)

template::value> struct value_if { };
template struct value_if
: map_integral { };

} // detail

// the fold_left and fold_right meta-something-or-others
// perform an unraveled fold in a strange way:
//'fold_left::step::step::step::type'
//
//effectively yields:
//op(transform(Z), op(transform(Y), op(transform(X), state)))
//
// vice versa with fold_right.
//
// These 'metafunctions' contain a nested template 'step'
// which represents a fold step.  These nested templates
// inject there own name via inheritance of their parent
// classes.  This allows the syntax:
fold_left<...>::step::step
// etc..  I'm not sure if this is actually legal, but it works on Comeau
C++.
// If it isn't legal, I'd need some kind of jumper typedef that identifies
the
// base class, which would alter the final syntax to:
// fold_left<...>::step::base::step etc.
// ...which is trivial handled by local sugar macros anyway.
//
// the 'op' parameter is the fold operation, which is instantiated
// with the current element and the current state.
//
// the 'state' parameter is the initial state of the accumulation
//
// the 'transform' parameter is a simple way to modify each element
// however you like.  The 'is_present' implementation uses this parameter
// with a partially bound 'is_same' metafunction, and uses a logical-or
// metafunction as the 'op' parameter.  The 'identity' metafunction is
// the default and simply does nothing.

// fold_left

template<
template class op,
class state,
template class transform = identity
>
struct fold_left {
template<
class element,
class apply = typename op<
typename transform::type, state
>::type
>
struct step :
fold_left,
detail::value_if,
identity { };
};

// fold_right

template<
template class op,
class state,
template class transform = identity,
class previous = detail::fold_nil
>
struct fold_right {
template struct step
: fold_right<
 

Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-09 Thread Terje Slettebø
>From: "David B. Held" <[EMAIL PROTECTED]>

> "Paul Mensonides" <[EMAIL PROTECTED]> wrote in message
> 000901c2b823$1e7f4aa0$8c00a8c0@c161550b">news:000901c2b823$1e7f4aa0$8c00a8c0@c161550b...
> From: "Terje Slettebø" <[EMAIL PROTECTED]>
>
> > [...]
> > BOOST_STATIC_ASSERT((\
> >   boost::is_same::value ||\
> >   boost::is_same::value ||\
> >   boost::is_same::value ||\
> >   boost::is_same::value ));
>
> And this is still bulkier and less elegant than the two-line MPL solution.
> ;)

I agree. I had actually missed Dave Abrahams (lastname used, as there's a
lot of Dave's here. :) ) solution, but I found it, now. I think was an
elegant way of doing it.

And, yeah, I didn't think of that you don't need backslashes when _calling_
a macro, only when defining it.


Regards,

Terje

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



Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-09 Thread Paul Mensonides

- Original Message -
From: "David B. Held" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, January 09, 2003 1:16 PM
Subject: [boost] Re: Re: How to do this in
withboost--assert(typeid(T)==typeid(bool) )


> "Paul Mensonides" <[EMAIL PROTECTED]> wrote in message
> 000901c2b823$1e7f4aa0$8c00a8c0@c161550b">news:000901c2b823$1e7f4aa0$8c00a8c0@c161550b...
> - Original Message -
> From: "Terje Slettebø" <[EMAIL PROTECTED]>
>
> > [...]
> > BOOST_STATIC_ASSERT((\
> >   boost::is_same::value ||\
> >   boost::is_same::value ||\
> >   boost::is_same::value ||\
> >   boost::is_same::value ));
>
> And this is still bulkier and less elegant than the two-line MPL solution.
> ;)

Which could be even shorter yet if we could get away with template template
parameters.

Paul Mensonides

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



Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )

2003-01-09 Thread David Abrahams
"Paul Mensonides" <[EMAIL PROTECTED]> writes:

> Which could be even shorter yet if we could get away with template
> template parameters.

We can and do.  

How would you imagine it would be spelled with TTP?

-- 
   David Abrahams
   [EMAIL PROTECTED] * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution

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