edouarda/brigand

is there a way to add std::index_sequence to 'for_each' function ?

GerwazyMiod opened this issue · 3 comments

I would like to iterate over brigand::list types, but but with information about type's index in brigand::list.

Is there a way to have struct with operator() with additional argument, passed to brigand::for_each, so I can have:

template<std::size_t... Is>
struct data_getter 
{
 void operator()(brigand::type_<int> t, std::index_sequence<Is...>);
 void operator()(brigand::type_<double> t, std::index_sequence<Is...>);
}

I would like to do a runtime operation on each type from brigand::list, and insert value to std::tuple, so I need std::tuple type index for std::get.

I've managed to add a runtime index, but it's not good for std::get, and for that we would need to have templated operator()

namespace detailed_
  {
    template<class F, class...Ts, std::size_t... Is> F for_each_args(F f, std::index_sequence<Is...>, Ts&&...a)
    {
        return (void)std::initializer_list<int>{((void)std::ref(f)(static_cast<Ts&&>(a), Is), 0)...}, f;
    }

    template<template<class...> class List, typename... Elements, typename Functor>
    Functor for_each_impl_indexed(List<Elements...>&&, Functor f)
    {
        return detailed_::for_each_args(f, std::index_sequence_for<Elements...>{}, type_<Elements>()...);
    }
  }//namespace detailed_

  template<typename List, typename Functor> Functor for_each_indexed(Functor f)
  {
      return detailed_::for_each_impl_indexed(List{}, f);
  }

pass Is as a std::integral_constant<int,Is> to your function so you can reuse is in a constexpr context

Thanks. Mind exploded, answer was so simple.