/ / Boost hana získať index prvého prispôsobenia - c ++, c ++ 11, boost, template-meta-programming, boost-hana

Boost hana získať index prvého prispôsobenia - c ++, c ++ 11, boost, template-meta-programming, boost-hana

Takže sa snažím vytvoriť knižnicu boost::hana ktorý vyžaduje funkčnosť na získanie indexu prvku na základe hodnoty:

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>

Existuje možný spôsob, ako to urobiť? Ešte lepšie, je už v ňom hana a neviem o tom?

Vďaka za podporu!

odpovede:

4 pre odpoveď č. 1

Hana neposkytuje algoritmus na tovon z krabice. Ak sa zdá, že je to veľmi žiadaná funkcia, mohol by som takýto algoritmus pridať pomerne ľahko. Pravdepodobne by sa dobre hodilo ako súčasť rozhrania ktoréhokoľvek Iterable, pretože Iterables sú tie sekvencie, pre ktoré sú indexy zmysluplné.

V súčasnej dobe by som ísť s niečím veľmi blízko k tomu, čo @ cv_and_he navrhol vo svojom komentári:

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

Niekoľko poznámok o vyššie uvedenom kóde. Po prvé, indexy musia byť v Hane negatívne, takže je pravdepodobne dobrý nápad použiť nepodpísaný typ. Po druhé, ja používam hana::drop_while namiesto hana::take_while, pretože prvý vyžaduje len Iterable, zatiaľ čo druhý vyžaduje Sequence, Hoci sa to môže zdať, že robím viac práce(výpočet veľkosti dvakrát), ukáže sa, že výpočet veľkosti väčšiny sekvencií, s ktorými sa stretnete, je veľmi rýchly, takže sa naozaj netýka. Nakoniec som uzavrela hana::size(hana::drop_while(...)) v decltype, čo zaručuje, že počas práce nebude vykonaná žiadna práca.


0 pre odpoveď č. 2

Čo sa týka používania 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;
}