/ / Boost hana obtener índice de primera coincidencia - c ++, c ++ 11, impulso, plantilla-meta-programación, boost-hana

Boost hana obtener el índice de la primera coincidencia - c ++, c + + 11, impulso, plantilla-meta-programación, boost-hana

Así que estoy tratando de hacer una biblioteca usando boost::hana eso requiere la funcionalidad para obtener el índice de un elemento basado en el valor:

constexpr auto tup = boost::hana::make_tuple(3_c, boost::hana::type_c<bool>);

auto index = get_index_of_first_matching(tup, boost::hana::type_c<bool>);
//   ^^^^^ would be a boost::hana::int_<1>

¿Hay una manera posible de hacer esto? Mejor aún, ¿ya está en hana y no lo sé?

¡Gracias por el apoyo!

Respuestas

4 para la respuesta № 1

Hana no proporciona un algoritmo para hacer estofuera de la caja. Si parece una característica muy deseada, podría agregar tal algoritmo con bastante facilidad. Probablemente encajaría bien como parte de la interfaz de cualquier Iterable, ya que Iterables son aquellas secuencias para las cuales los índices son significativos.

Por el momento, iría con algo muy cercano a lo que @cv_and_he propuso en su comentario:

#include <boost/hana.hpp>
namespace hana = boost::hana;

template <typename Iterable, typename T>
constexpr auto index_of(Iterable const& iterable, T const& element) {
auto size = decltype(hana::size(iterable)){};
auto dropped = decltype(hana::size(
hana::drop_while(iterable, hana::not_equal.to(element))
)){};
return size - dropped;
}

constexpr auto tuple = hana::make_tuple(hana::int_c<3>, hana::type_c<bool>);
constexpr auto index = index_of(tuple, hana::type_c<bool>);
static_assert(index == hana::size_c<1>, "");

int main() { }

Algunas notas sobre el código anterior. Primero, se requiere que los índices sean no negativos en Hana, por lo que probablemente sea una buena idea usar un tipo sin firmar. En segundo lugar, estoy usando hana::drop_while en lugar de hana::take_while, porque el primero solo requiere una Iterable, mientras que el segundo requiere una Sequence. Si bien puede parecer que estoy haciendo más trabajo(calculando el tamaño dos veces), resulta que calcular el tamaño de la mayoría de las secuencias que encontrarás es muy rápido, por lo que no es realmente una preocupación. Finalmente, estoy adjuntando el hana::size(hana::drop_while(...)) en decltype, lo que garantiza que no se realizará ningún trabajo en tiempo de ejecución.


0 para la respuesta № 2

¿Qué hay de usar boost::detail::index_if:

#include <boost/hana.hpp>

template <typename Haystack, typename Needle>
constexpr auto get_index_of_first_matching(Haystack&&, Needle&& n)
{
using Pred = decltype(boost::hana::equal.to(n));
using Pack = typename boost::hana::detail::make_pack<Haystack>::type;
constexpr auto index = boost::hana::detail::index_if<Pred, Pack>::value;
return boost::hana::int_c<index>;
}

int main()
{
using namespace boost::hana::literals;
constexpr auto tup = boost::hana::make_tuple(3_c, boost::hana::type_c<bool>);
constexpr auto index = get_index_of_first_matching(tup, boost::hana::type_c<bool>);
static_assert(index == boost::hana::int_c<1>, "index is wrong");
return 0;
}