/ / Boost hana отримати індекс першої відповідності - c + +, c + + 11, boost, шаблон-мета-програмування, boost-hana

Boost hana отримує індекс першої відповідності - c ++, c ++ 11, boost, template-meta-programming, boost-hana

Отже, я намагаюся використовувати бібліотеку boost::hana що вимагає функціональності отримати індекс елемента на основі значення:

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>

Чи можливий спосіб зробити це? Поки ще краще, це вже в Росії hana і я не знаю про це?

Дякую за підтримку!

Відповіді:

4 для відповіді № 1

Хана не надає алгоритму для цьогоз коробки. Якщо це здається набагато бажаною функцією, я міг би легко додати такий алгоритм. Це, ймовірно, добре підходить як частина інтерфейсу будь-якого Iterable, оскільки IterableS - це ті послідовності, для яких показники мають сенс.

Поки що я хотів би піти з чимось дуже близьким до того, що запропонував його @cv_and_he у своєму коментарі:

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

Кілька зауважень щодо вищезазначеного коду. По-перше, показники повинні бути неотрицательними в Хані, тому, ймовірно, хороша ідея використовувати непідписаний тип. По-друге, я використовую hana::drop_while замість hana::take_while, тому що перший вимагає лише Iterable, тоді як останній вимагає a Sequence. Хоча може здатися, що я роблю більше роботи(обчислення розміру вдвічі), виявляється, що обчислення розміру більшості послідовностей, з якими ви зіштовхнетеся, дуже швидко, тому це не викликає занепокоєння. Нарешті, я додаю hana::size(hana::drop_while(...)) в decltype, що гарантує, що під час виконання не буде виконана ніяка робота.


0 для відповіді № 2

Як щодо використання 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;
}