Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )
- 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) )
"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) )
- 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) )
"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) )
- 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) )
>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) )
- 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) )
"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