/ / Boost hana ottiene l'indice della prima corrispondenza - c ++, c ++ 11, boost, template-meta-programming, boost-hana

Boost hana ha l'indice della prima corrispondenza - c ++, c ++ 11, boost, template-meta-programming, boost-hana

Quindi sto cercando di far usare una libreria boost::hana che richiede la funzionalità per ottenere l'indice di un elemento in base al valore:

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>

C'è un modo possibile per fare questo? Meglio ancora, è già in hana e non lo so?

Grazie per il supporto!

risposte:

4 per risposta № 1

Hana non fornisce un algoritmo per farlofuori dalla scatola. Se sembra una caratteristica tanto desiderata, potrei aggiungere un tale algoritmo abbastanza facilmente. Probabilmente si adatterebbe bene come parte dell'interfaccia di qualsiasi Iterable, da Iterables sono quelle sequenze per le quali gli indici sono significativi.

Per il momento, vorrei andare con qualcosa di molto vicino a ciò che @cv_and_he ha proposto nel suo commento:

#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() { }

Alcune note sul codice di cui sopra. Innanzitutto, gli indici devono essere non negativi in ​​Hana, quindi è probabilmente una buona idea usare un tipo senza segno. In secondo luogo, sto usando hana::drop_while invece di hana::take_while, perché il primo richiede solo un Iterable, mentre il secondo richiede a Sequence. Mentre può sembrare che sto facendo più lavoro(calcolando la dimensione due volte), risulta che calcolare la dimensione della maggior parte delle sequenze che incontrerai è molto veloce, quindi non è davvero una preoccupazione. Alla fine, accludo il hana::size(hana::drop_while(...)) in decltype, che garantisce che nessun lavoro verrà eseguito in fase di esecuzione.


0 per risposta № 2

Che ne dici di usare 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;
}