|
| 1 | +#ifndef STAN_MATH_PRIM_FUNCTOR_APPLY_HPP |
| 2 | +#define STAN_MATH_PRIM_FUNCTOR_APPLY_HPP |
| 3 | + |
| 4 | +#include <functional> |
| 5 | +#include <tuple> |
| 6 | +#include <utility> |
| 7 | + |
| 8 | +namespace stan { |
| 9 | +namespace math { |
| 10 | +namespace internal { |
| 11 | +/* |
| 12 | + * Invoke the functor f with arguments given in t and indexed in the index |
| 13 | + * sequence I |
| 14 | + * |
| 15 | + * @tparam F Type of functor |
| 16 | + * @tparam Tuple Type of tuple containing arguments |
| 17 | + * @tparam I Parameter pack of an index sequence going from 0 to |
| 18 | + * std::tuple_size<T>::value - 1 inclusive |
| 19 | + * @param f functor callable |
| 20 | + * @param t tuple of arguments |
| 21 | + * @param i placeholder variable for index sequence |
| 22 | + */ |
| 23 | +template <class F, class Tuple, std::size_t... I> |
| 24 | +constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, |
| 25 | + std::index_sequence<I...> i) { |
| 26 | + return f(std::forward<decltype(std::get<I>(t))>(std::get<I>(t))...); |
| 27 | +} |
| 28 | +} // namespace internal |
| 29 | +/* |
| 30 | + * Call the functor f with the tuple of arguments t, like: |
| 31 | + * |
| 32 | + * f(std::get<0>(t), std::get<1>(t), ...) |
| 33 | + * |
| 34 | + * TODO: replace this with implementation in C++ std when C++17 is available |
| 35 | + * |
| 36 | + * @tparam F Type of functor |
| 37 | + * @tparam Tuple Type of tuple containing arguments |
| 38 | + * @param f functor callable |
| 39 | + * @param t tuple of arguments |
| 40 | + */ |
| 41 | +template <class F, class Tuple> |
| 42 | +constexpr decltype(auto) apply(F&& f, Tuple&& t) { |
| 43 | + return internal::apply_impl( |
| 44 | + std::forward<F>(f), std::forward<Tuple>(t), |
| 45 | + std::make_index_sequence< |
| 46 | + std::tuple_size<std::remove_reference_t<Tuple>>{}>{}); |
| 47 | +} |
| 48 | + |
| 49 | +} // namespace math |
| 50 | +} // namespace stan |
| 51 | + |
| 52 | +#endif |
0 commit comments