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_invokerSequence, 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_castmpl::at_cSequence, 0::type
*(storage)));
case 1:
return op(*(static_castmpl::at_cSequence, 1::type
*(storage)));
case 2:
return op(*(static_castmpl::at_cSequence, 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_invokermy_seq, 3, the template
machinery should match the above specialization, and the statement,
n_ary_rtts_invokermy_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=index3).
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