/ / Boost Hana Index der ersten Übereinstimmung erhalten - C ++, C ++ 11, Boost, Template-Meta-Programmierung, Boost-Hana

Boost Hana erhalten Index der ersten Übereinstimmung - C ++, C ++ 11, Boost, Vorlage-Meta-Programmierung, Boost-Hana

Also versuche ich eine Bibliothek mit zu machen boost::hana das erfordert die Funktionalität, um den Index eines Elements basierend auf dem Wert zu erhalten:

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>

Gibt es einen möglichen Weg, dies zu tun? Besser noch, ist es schon drin hana und ich weiß es nicht?

Danke für die Unterstützung!

Antworten:

4 für die Antwort № 1

Hana bietet dafür keinen Algorithmus anOut-of-the-Box. Wenn es wie eine sehr erwünschte Funktion erscheint, könnte ich einen solchen Algorithmus relativ einfach hinzufügen. Es würde wahrscheinlich gut als Teil der Schnittstelle von jedem passen Iterable, schon seit Iterables sind diejenigen Sequenzen, für die Indizes sinnvoll sind.

Vorläufig würde ich mit etwas gehen, was sehr nah an dem ist, was @cv_and_he in seinem Kommentar vorgeschlagen hat:

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

Ein paar Anmerkungen zum obigen Code. Erstens müssen Indizes in Hana nicht negativ sein, daher ist es wahrscheinlich eine gute Idee, einen vorzeichenlosen Typ zu verwenden. Zweitens benutze ich hana::drop_while Anstatt von hana::take_while, weil erstere nur ein benötigt Iterable, während letzteres eine erfordert Sequence. Obwohl es so aussieht, als würde ich mehr arbeiten(Berechnung der Größe zweimal), es stellt sich heraus, dass die Berechnung der Größe der meisten Sequenzen, die Sie begegnen, ist sehr schnell, so ist es nicht wirklich ein Anliegen. Schließlich schließe ich die hana::size(hana::drop_while(...)) im decltype, wodurch sichergestellt wird, dass zur Laufzeit keinerlei Arbeit geleistet wird.


0 für die Antwort № 2

Wie wäre es mit der Verwendung? 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;
}