Brian Simpson wrote: > The implementation reasoning runs like this: It seems that the problem with > building a switch statement to implement type selection is that a switch > statement can't be built incrementally--it is a syntactic construct. (The > currently accepted solution builds an else-if-then statement incrementally > by means of a recursive function template instantiation.) But what if you > could give a template the number of types among which you want to select in > addition to the sequence? Could it then implement a switch-based selection > on the first 'n' types in the sequence? The answer turns out to be yes, up > to a point. The mechanism, in this case, is partial template > specialization. > Let us define a template class: > template <typename Sequence, long n> > class n_ary_rtts_invoker; > How does it produce a switch statement based on 'n'? Well, if we limit > ourselves to a specific value of 'n', we can express it. For example, here > is a specialization for 'n'==3: > <code> > template <typename Sequence> > class rtts_invoker<Sequence, 3> > { > public: > template <typename Operator, typename StoragePtr> > static > BOOST_DEDUCED_TYPENAME Operator::result_type > invoke(Operator & op, StoragePtr storage, long index) > { > switch (index) > { > case 0: > return op(*(static_cast<mpl::at_c<Sequence, 0>::type > *>(storage))); > case 1: > return op(*(static_cast<mpl::at_c<Sequence, 1>::type > *>(storage))); > case 2: > return op(*(static_cast<mpl::at_c<Sequence, 2>::type > *>(storage))); > } > } > }; > </code> > Given this specialization of n_ary_rtts_invoker, we can setup runtime type > selection on the first three types in a sequence. To be more specific, if > we instantiate a type, "n_ary_rtts_invoker<my_seq, 3>", the template > machinery should match the above specialization, and the statement, > "n_ary_rtts_invoker<my_seq, 3>::invoke(my_op, storage, index)", will make a > selection among the first three types in 'my_seq' via a switch statement > (assuming 0<=index<3). > If we define a similar specialization for values 1 and 2, we can setup > selection on sequences of size 1-3. > > The general case devolves into an else-if-then: > Let us assume that we have specializations up to a certain number, > 'max_specialization_count'. Then we know that we can get switch-based > runtime type selection ("rtts") on any mpl::Sequence whose size is not > greater than 'max_specialization_count'. To provide rtts for Sequences > whose size is greater than 'max_specialization_count', we provide a more > general template definition. Its "invoke" function sets up a switch-based > selection among the first 'max_specialization_count' types, and then sets up > a (recursive) selection among the remaining types.
FWIW, I've used a similar technique in MPL to do recursion unrolling for the 'advance' algorithm: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/boost/mpl/aux_/preprocessed/plain/advance_forward.hpp?rev=1.4 Aleksey _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost