|
Boost : |
From: Hugo Duncan (hugoduncan_at_[hidden])
Date: 2003-10-23 14:18:41
David B. Held <dheld_at_[hidden]> wrote:
> Sounds close, but I can't look at your code because my
> newsreader doesn't have that thread, and the web-based
> ones try to interpret your attachment as HTML.
It's so short, I'll include it here :-)
Hugo
#include <boost/mpl/apply.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/aux_/unwrap.hpp>
#include <boost/utility/value_init.hpp>
namespace ieg
{
namespace detail
{
template <bool done = true>
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<false>
{
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<TransformFunc,item>::type arg;
// make sure not to invoke undefined behavior when we pass arg.
boost::value_initialized<arg> x;
boost::mpl::aux::unwrap(f, 0)(boost::get(x));
}
else
{
typedef typename Iterator::next iter;
typedef typename Counter::next counter;
switcher_impl<boost::is_same<iter,LastIterator>::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 <typename Sequence, typename TransformOp, typename F>
void switcher(F f, std::size_t i, Sequence* = 0, TransformOp* = 0)
{
typedef typename boost::mpl::begin<Sequence>::type first;
typedef typename boost::mpl::end<Sequence>::type last;
typedef typename boost::mpl::lambda<TransformOp>::type transform_op;
typedef typename boost::mpl::integral_c<std::size_t,0>::type counter;
detail::switcher_impl< boost::is_same<first,last>::value >::execute(
(first*)0, (last*)0, (transform_op*)0, f, (counter*)0, i);
}
template <typename Sequence, typename F>
void switcher(F f, std::size_t i, Sequence* = 0)
{
switcher<Sequence, boost::mpl::make_identity<> >(f,i);
}
}// namespace
#include <cstdlib>
#include <typeinfo>
#include <iostream>
#include <boost/mpl/vector.hpp>
struct myfn
{
template < typename U > void operator()(const boost::mpl::identity<U>&)
{
std::cout << typeid(U).name() << std::endl;
}
};
int main()
{
typedef boost::mpl::vector<double, float> my_typelist;
for (int i=0; i<2; ++i)
ieg::switcher<my_typelist>(myfn(),i);
ieg::switcher<my_typelist>(myfn(),1);
ieg::switcher<my_typelist>(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