apply

関数オブジェクトとtupleを渡すとtupleの各要素を引数として関数を呼び出すいわゆるapplyの動作をする関数を実装してみました。sproutには既にmake_fusedという非常に便利な関数があるのでこれを適用した後に関数を呼び出す処理までをラップすれば同じ効果が得られるといえます。

可変長のsumはgccではまだC++1yのconstexprが未実装っぽく(副作用が使えなかった)てコケました。

#include <sprout/tuple.hpp>
#include <sprout/array.hpp>
#include <sprout/utility.hpp>
#include <sprout/functional.hpp>

template <typename Function, typename Tuple>
constexpr auto apply(Function&& f, Tuple&& t) {
  return sprout::make_fused(sprout::forward<Function>(f))(
      sprout::forward<Tuple>(t));
}

struct sum {
  template <typename... Types>
  constexpr auto operator()(Types&&... Args) const {
    using result_type = typename sprout::common_type<Types...>::type;
    result_type result = 0;
    for (auto&& elem : sprout::make_array<result_type>(
             sprout::forward<result_type>(Args)...)) {
      result += elem;
    }
    return result;
  }
};

int main() {
  constexpr auto result =
      apply(sum(), sprout::make_tuple(1, 2, 3, 4, 5, 6, 7, 8, 9));
  static_assert(result == 45, "");
}

単なるplusはgccでも通りました。

#include <sprout/tuple.hpp>
#include <sprout/utility.hpp>
#include <sprout/functional.hpp>

template <typename Function, typename Tuple>
constexpr auto apply(Function&& f, Tuple&& t) {
  return sprout::make_fused(sprout::forward<Function>(f))(
      sprout::forward<Tuple>(t));
}

int main() {
  constexpr auto result =
      apply(sprout::plus<>(), sprout::make_tuple(1, 2));
  static_assert(result == 3, "");
}