c++ - How to apply a tuple of actions on tuple of numbers? -


i have 2 tuples, 1 containing values , tuple containing actions these values. want apply corresponding action on each value, little code "overhead" possible. simplified example below.

#include <iostream> #include <boost/hana.hpp>  namespace hana = boost::hana; using namespace hana::literals;   struct thinkpositive {     void operator()(int &val) const     {         std::cout << "think positive!\n";         val = std::abs(val);     } };  struct nice {     void operator()(int &val) const     {         std::cout << val << " nice!\n";     } };  void numbers() {     auto handlers = hana::make_tuple(nice{}, thinkpositive{});     auto nums = hana::make_tuple(5, -12);     auto handlers_and_nums = hana::zip(handlers, nums);      hana::for_each(handlers_and_nums, [](auto &handler_num) {         handler_num[0_c](handler_num[1_c]);     });      auto result = hana::transform(handlers_and_nums, [](const auto &handler_num) {         return handler_num[1_c];     });      hana::for_each(result, [](const auto num) {         std::cout << "got " << num << '\n';     }); }  int main() {     numbers(); } 

while example above works nicer modify contents of nums in place.

is there way modify nums in place?

you use zip_with, seems against nature (it requires function return something, operators () return nothing:

auto special_compose = [](auto&& l, auto&& r){ l(r); return 0; }; hana::zip_with(special_compose, handlers, nums); 

demo


if can make operators return something, go lockstep:

hana::fuse(hana::fuse(hana::lockstep(hana::always(0)))(handlers))(nums); 

demo

there should lockstep defined without outer f call, found nothing in docs.


a little more standard solution (won't fit requirement of little code overhead possible):

template<typename fs, typename params, size_t... is> void apply_in_lockstep_impl(fs&& fs, params&& ps, std::index_sequence<is...>){     int x[] = { (fs[hana::integral_c<size_t,is>](ps[hana::integral_c<size_t,is>]),0)... }; }  template<typename fs, typename params> void apply_in_lockstep(fs&& fs, params&& ps){     static_assert(hana::size(fs) == hana::size(ps), "");     apply_in_lockstep_impl(std::forward<fs>(fs),                            std::forward<params>(ps),                            std::make_index_sequence<decltype(hana::size(ps))::value>{}); } 

but @ call site prettier:

apply_in_lockstep(handlers, nums); 

demo


as pointed in comments level of indirection can help. here mean transform sequence sequence of pointer, via original values modified.

auto nums_ptr = hana::transform(nums, [](auto &num) { return &num; }); auto handlers_and_nums = hana::zip(handlers, nums_ptr); hana::for_each(handlers_and_nums, [](auto &handler_num) {     handler_num[0_c](*handler_num[1_c]); }); 

demo


another, more "traditional", way iterate on range. using old loop.

auto indices = hana::make_range(0_c, hana::length(handlers)); hana::for_each(indices, [&](auto i) {     handlers[i](nums[i]); }); 

demo


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -