Boost::Hana 元组,修改值的最佳方式
Boost::Hana tuple, best way to modify a value
我对这个功能强大的库还很陌生。我很惊讶我找不到一个简单的方法,给定一个元组,return另一个只修改单个元素的元组,按索引。
此外,我希望此方法也可用于 编译时
例如:
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));
我想我可以通过组合插入和 remove_at 来实现这个结果,但我想知道是否有更有效的方法来做到这一点
为了让其他人明白 "modify a value" 意味着改变 运行 时间值,hana::at
and hana::at_c
以及相应的 operator[]
可以 return 可变引用以在 运行 时更改值。这不会更改元素的类型:
hana::at_c<1>(tup) = 2000;
就替换元素类型和所有元素而言,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));
这比组合其他依赖于创建中间元组来随机排列值的函数更有效。
我对这个功能强大的库还很陌生。我很惊讶我找不到一个简单的方法,给定一个元组,return另一个只修改单个元素的元组,按索引。
此外,我希望此方法也可用于 编译时
例如:
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));
我想我可以通过组合插入和 remove_at 来实现这个结果,但我想知道是否有更有效的方法来做到这一点
为了让其他人明白 "modify a value" 意味着改变 运行 时间值,hana::at
and hana::at_c
以及相应的 operator[]
可以 return 可变引用以在 运行 时更改值。这不会更改元素的类型:
hana::at_c<1>(tup) = 2000;
就替换元素类型和所有元素而言,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));
这比组合其他依赖于创建中间元组来随机排列值的函数更有效。