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]

 snip

 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 {
 templateclass T struct actual_metafunction {
 // ...
 };
 };

 vs.

 templateclass T 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:

 containsT::argint::argdouble::argstd::string::value

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

 containsT
 ::template argint
 ::template argdouble
 ::template argstd::string
 ::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-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 {
  templateclass T struct actual_metafunction {
  // ...
  };
  };
 
  vs.
 
  templateclass T 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-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::stepX::stepY::stepZ::[ 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_presentT
 item bool
 item int
 item double
 item std::string
 ::value


snip

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-10 Thread Paul Mensonides
- Original Message -
From: David Abrahams [EMAIL PROTECTED]

 snip

 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 {
templateclass T struct actual_metafunction {
// ...
};
};

vs.

templateclass T 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:

containsT::argint::argdouble::argstd::string::value

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

containsT
::template argint
::template argdouble
::template argstd::string
::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-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



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_sameT, bool::value ||\
boost::is_sameT, int::value ||\
boost::is_sameT, double::value ||\
boost::is_sameT, std::string::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 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_sameT, bool::value ||\
boost::is_sameT, int::value ||\
boost::is_sameT, double::value ||\
boost::is_sameT, std::string::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 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::stepX::stepY::stepZ::[ 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_presentT
item bool
item int
item double
item std::string
::value

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

typedef gen_typelist
item char
item signed char
item unsigned char
item short
item unsigned short
item int
item unsigned
item long
item unsigned long
::type integral_types;

Here is the implementation (from scratch):

// identity:  yields its template argument as a typedef

templateclass T 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.)

templateclass T, T V struct map_integral : identityT {
static const T value = V;
};

templateclass T, T V const T map_integralT, V::value;

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

templateclass T struct has_member_value {
private:
templatelong struct helper;
templateclass U static char check(helperU::value*);
templateclass U static char ( check(...))[2];
public:
static const bool value = sizeof(checkT(0)) == 1;
};

templateclass T const bool has_member_valueT::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

templateclass parent, class element struct fold_helper { };

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

templateclass build, class struct fold_reversal;

// specialization for no previous state

templateclass build struct fold_reversalbuild, fold_nil {
typedef build type;
};

// specialization otherwise

templateclass build, class parent, class element
struct fold_reversalbuild, fold_helperparent, element  {
typedef typename fold_reversal
typename build::template stepelement, 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.)

templateclass T, bool = has_member_valueT::value struct value_if { };
templateclass T struct value_ifT, true
: map_integraltypename T::type, T::value { };

} // detail

// the fold_left and fold_right meta-something-or-others
// perform an unraveled fold in a strange way:
//'fold_leftop, state, transform::stepX::stepY::stepZ::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...::stepint::stepdouble
// 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...::stepint::base::stepdouble 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
templateclass _element, class _state class op,
class state,
templateclass class transform = identity

struct fold_left {