|
Boost :
|
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