Boost :: Hana tuple, лучший способ изменить значение - PullRequest
2 голосов
/ 15 апреля 2020

Я довольно новичок в этой мощной библиотеке. Я был удивлен, что не смог найти простой способ, учитывая данный кортеж, вернуть другой кортеж, который просто изменяет один элемент, по индексу.

Более того, я хочу, чтобы этот метод был доступен также на время компиляции

Например:

auto tup = hana::make_tuple(1_c,2_c,3_c);
static_assert(modify(tup,1,2000_c) == hana::make_tuple(1_c,2000_c,3_c));

Я думаю, что могу достичь этого результата, комбинируя insert и remove_at, но мне интересно, есть ли более эффективный способ сделать это

1 Ответ

2 голосов
/ 16 апреля 2020

Просто чтобы быть понятным другим, которые могут найти «изменить значение», означающее изменение значения времени выполнения, hana::at и hana::at_c, а также соответствующие operator[] может возвращать изменяемые ссылки для изменения значения во время выполнения. Это не меняет тип элемента:

hana::at_c<1>(tup) = 2000;

https://godbolt.org/z/xErFNm

Что касается замены типа элемента и всего, Boost.Hana не поддерживает Это напрямую, но, глядя на реализацию remove_at, реализация replace_at проста:

#include <boost/hana.hpp>
#include <utility>

namespace hana = boost::hana;
using namespace hana::literals;

template <typename Xs, typename X, std::size_t ...before, std::size_t ...after>
constexpr auto replace_at_helper(Xs&& xs, X&&x, std::index_sequence<before...>,
                                      std::index_sequence<after...>) {
  return hana::make_tuple(
      hana::at_c<before>(std::forward<Xs>(xs))...,
      std::forward<X>(x),
      hana::at_c<after + sizeof...(before) + 1>(std::forward<Xs>(xs))...);
}

template <std::size_t n>
constexpr auto replace_at_c = [](auto&& xs, auto&& x) {
    constexpr auto len = decltype(hana::length(xs))::value;
    return replace_at_helper(static_cast<decltype(xs)>(xs),
                             static_cast<decltype(x)>(x),
                             std::make_index_sequence<n>{},
                             std::make_index_sequence<len - n - 1>{});
};

auto tup = hana::make_tuple(1_c,2_c,3_c);
static_assert(replace_at_c<1>(tup,2000_c) == hana::make_tuple(1_c,2000_c,3_c));

https://godbolt.org/z/H2aySg

Это более эффективно чем составление других функций, которые будут полагаться на создание промежуточных кортежей для перемешивания значений вокруг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...