Boost logo

Boost :

From: Hugo Duncan (hugoduncan_at_[hidden])
Date: 2003-10-10 13:30:09


Hugo Duncan <hugoduncan_at_[hidden]> wrote:

> Hugo Duncan <hugoduncan_at_[hidden]> wrote:
>
>> I'm looking for the following MPL functionality and wondering if it
>> already exists somewhere.

> The implementation with for_each is very inefficient, using a
> local counter. There must be a better way...

And so there is. Attatched is a version that effectively uses
mpl::for_each's
implementation with an additional integer argument, only calling the
template
function object for the relevant index.

Any chance of getting something similar into MPL?

Hugo

#include #include #include #include #include #include #include namespace ieg { namespace detail { template struct switcher_impl { template< typename Iterator , typename LastIterator , typename TransformFunc , typename F , typename Counter > static void execute( Iterator* , LastIterator* , TransformFunc* , F , Counter* , std::size_t i ) { } }; template <> struct switcher_impl { template< typename Iterator , typename LastIterator , typename TransformFunc , typename F , typename Counter > static void execute( Iterator* , LastIterator* , TransformFunc* , F f , Counter* , std::size_t i ) { if (i==Counter::value) { typedef typename Iterator::type item; typedef typename boost::mpl::apply1::type arg; // make sure not to invoke undefined behavior when we pass arg. boost::value_initialized x; boost::mpl::aux::unwrap(f, 0)(boost::get(x)); } else { typedef typename Iterator::next iter; typedef typename Counter::next counter; switcher_impl::value>::execute( (iter*)0, (LastIterator*)0, (TransformFunc*)0, f, (counter*)0, i); } } }; } //! exectute a metafunction on an run-time selected element of type sequence template void switcher(F f, std::size_t i, Sequence* = 0, TransformOp* = 0) { typedef typename boost::mpl::begin::type first; typedef typename boost::mpl::end::type last; typedef typename boost::mpl::lambda::type transform_op; typedef typename boost::mpl::integral_c::type counter; detail::switcher_impl< boost::is_same::value >::execute( (first*)0, (last*)0, (transform_op*)0, f, (counter*)0, i); } template void switcher(F f, std::size_t i, Sequence* = 0) { switcher >(f,i); } }// namespace #include #include #include #include struct myfn { template < typename U > void operator()(const boost::mpl::identity&) { std::cout << typeid(U).name() << std::endl; } }; int main() { typedef boost::mpl::vector my_typelist; for (int i=0; i<2; ++i) ieg::switcher(myfn(),i); ieg::switcher(myfn(),1); ieg::switcher(myfn(),2);//< silent, no error }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk