Skip to content

Instantly share code, notes, and snippets.

@SteveBronder
Created July 8, 2020 19:11
Show Gist options
  • Select an option

  • Save SteveBronder/410f7127f8be9dced2b1915765fd8644 to your computer and use it in GitHub Desktop.

Select an option

Save SteveBronder/410f7127f8be9dced2b1915765fd8644 to your computer and use it in GitHub Desktop.
#ifndef STAN_MATH_PRIM_FUNCTOR_FOR_EACH_HPP
#define STAN_MATH_PRIM_FUNCTOR_FOR_EACH_HPP
#include <stan/math/prim/meta.hpp>
#include <functional>
#include <tuple>
#include <utility>
namespace stan {
namespace math {
namespace internal {
/**
* Implimentation of for_each.
* @note The static cast to void is used in boost::hana's for_each impl
* and is used to suppress unused value warnings from the compiler.
*/
template <typename F, typename T, size_t... Is>
constexpr inline auto for_each(F&& f, T&& t, std::index_sequence<Is...>) {
using Swallow = int[];
static_cast<void>(Swallow{
(static_cast<void>(std::forward<F>(f)(std::get<Is>(std::forward<T>(t)))),
0)...});
}
/**
* Implimentation of Binary for_each.
* @note The static cast to void is used in boost::hana's for_each impl
* and is used to suppress unused value warnings from the compiler.
*/
template <typename F, typename T1, typename T2, size_t... Is>
constexpr inline auto for_each(F&& f, T1&& t1, T2&& t2,
std::index_sequence<Is...>) {
using Swallow = int[];
static_cast<void>(Swallow{(
static_cast<void>(std::forward<F>(f)(std::get<Is>(std::forward<T1>(t1)),
std::get<Is>(std::forward<T2>(t2)))),
0)...});
}
} // namespace internal
/**
* Apply a function to each element of a tuple
* @tparam F type with a valid `operator()`
* @tparam T tuple
* @param f A functor to apply over each element of the tuple.
* @param t A tuple.
*/
template <typename F, typename T>
constexpr inline auto for_each(F&& f, T&& t) {
return internal::for_each(
std::forward<F>(f), std::forward<T>(t),
std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>());
}
/**
* Apply a function to each element of a tuple and other container
* @tparam F type with a valid `operator()`
* @tparam T1 tuple
* @tparam Any container with an `operator[]`
* @param f A functor to apply over each element of the tuple.
* @param t1 A tuple.
* @param t2 Any container with `operator[]`.
*/
template <typename F, typename T1, typename T2>
constexpr inline auto for_each(F&& f, T1&& t1, T2&& t2) {
return internal::for_each(
std::forward<F>(f), std::forward<T1>(t1), std::forward<T2>(t2),
std::make_index_sequence<std::tuple_size<std::decay_t<T1>>::value>());
}
} // namespace math
} // namespace stan
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment