Skip to content

Instantly share code, notes, and snippets.

@isc30
Last active January 31, 2018 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isc30/4a1f64848c0f08318ecb3330262373a5 to your computer and use it in GitHub Desktop.
Save isc30/4a1f64848c0f08318ecb3330262373a5 to your computer and use it in GitHub Desktop.
C++14 helpers to call functor using args stored in a tuple, array or vector
#include <iostream>
#include <array>
#include <vector>
#include <tuple>
#include <utility>
void printNumbers(int x, int y, int z)
{
std::cout << x << std::endl;
std::cout << y << std::endl;
std::cout << z << std::endl;
}
template<std::size_t Index, typename TElementType, typename TContainer>
constexpr typename std::enable_if<std::is_rvalue_reference<TElementType>::value, TElementType>::type get_forward_impl(TContainer&& container)
{
return std::move(std::get<Index>(container));
}
template<std::size_t Index, typename TElementType, typename TContainer>
constexpr typename std::enable_if<!std::is_rvalue_reference<TElementType>::value, const TElementType&>::type get_forward_impl(TContainer&& container)
{
return std::get<Index>(container);
}
template<std::size_t Index, typename... TTuple>
constexpr auto&& get_forward(const std::tuple<TTuple...>& tuple)
{
using TElement = std::tuple_element_t<Index, std::tuple<TTuple...>>;
return get_forward_impl<Index, TElement>(tuple);
}
template<std::size_t Index, typename TArray, std::size_t N>
constexpr auto&& get_forward(const std::array<TArray, N>& array)
{
return get_forward_impl<Index, TArray>(array);
}
template<std::size_t Index, typename TArray>
constexpr const auto& get_forward(const std::vector<TArray>& array)
{
return array[Index];
}
template<typename TFunctor, typename TContainer, std::size_t... Indices>
constexpr auto apply_sequence(TFunctor&& functor, TContainer&& container, std::index_sequence<Indices...>)
{
return functor(get_forward<Indices>(std::forward<TContainer>(container))...);
}
template<typename TFunctor, typename... TTuple>
constexpr auto apply_tuple(TFunctor&& functor, const std::tuple<TTuple...>& tuple)
{
return apply_sequence(std::forward<TFunctor>(functor), tuple, std::index_sequence_for<TTuple...>());
}
template<typename TFunctor, typename TArg, std::size_t N>
constexpr auto apply_array(TFunctor&& functor, const std::array<TArg, N>& args)
{
return apply_sequence(std::forward<TFunctor>(functor), args, std::make_index_sequence<N>());
}
template<std::size_t N, typename TFunctor, typename TArg>
constexpr auto apply_vector(TFunctor&& functor, const std::vector<TArg>& args)
{
return apply_sequence(std::forward<TFunctor>(functor), args, std::make_index_sequence<N>());
}
int main(int argc, char* argv[])
{
std::array<int, 3> xxx { 2, 5, 77 };
apply_array(printNumbers, xxx);
std::cout << "---------------" << std::endl;
std::vector<int> yyy { 3, 4, 5 };
apply_vector<3>(printNumbers, yyy);
std::cout << "---------------" << std::endl;
std::tuple<int, int, int> zzz { 1, 2, 3 };
apply_tuple(printNumbers, zzz);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment