Skip to content

Instantly share code, notes, and snippets.

@jfalcou
Created April 29, 2016 14:48
Show Gist options
  • Save jfalcou/73ac092884f6e8136212f1433db73ee1 to your computer and use it in GitHub Desktop.
Save jfalcou/73ac092884f6e8136212f1433db73ee1 to your computer and use it in GitHub Desktop.
C++ FRUG 07/04/2016
#include <initializer_list>
#include <functional>
#include <iostream>
#include <utility>
#include <tuple>
//--------------------------------------------------------
// Appliquer une fonction sur une ligne d'arguments
template<class F, class...Ts> F for_each_args(F f, Ts&&...a)
{
return (void)std::initializer_list<int>{((void)std::ref(f)(std::forward<Ts>(a)),0)...}, f;
}
//--------------------------------------------------------
// Appliquer une fonction sur chaque membres d'un tuple
namespace detail
{
template <class F, class Tuple, std::size_t... I>
decltype(auto) apply_impl( F&& f, Tuple&& t, std::index_sequence<I...> )
{
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
}
}
template <class F, class Tuple> decltype(auto) apply(F&& f, Tuple&& t)
{
return detail::apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>{}>{});
}
//--------------------------------------------------------
// Une reduction sans recursion
namespace detail
{
template <class Array, std::size_t... I>
decltype(auto) reduce_impl( Array const& a, std::index_sequence<I...> )
{
using type = typename Array::value_type;
type r{};
(void)std::initializer_list<type>{ (r+= a[I])... };
return r;
}
}
template<class Array> decltype(auto) reduce(Array const& a)
{
return detail::reduce_impl(a, std::make_index_sequence<std::tuple_size<Array>{}>{});
}
//--------------------------------------------------------
template<bool... B> struct bools_ {}
;
// Reduction de meta-predicat
template<template<class> class Pred, typename... T>
struct all : std::is_same< bools_<true , Pred<T>::value... >
, bools_<Pred<T>::value..., true >
>
{};
//--------------------------------------------------------
int main()
{
auto disp = [](auto x) { std::cout << x << " "; };
for_each_args( disp, 1,"3",5.f,"rofl",39u );
std::cout << "\n";
auto t = std::make_tuple(4,3.f,88u,'z');
apply( [&](auto const&... x) { for_each_args( disp, x... ); } , t);
std::cout << "\n";
std::array<float,5> ff{1,2,3,4,5};
std::cout << reduce(ff) << "\n";
using is_all_pointer = all< std::is_pointer, char*, void**, float****>;
std::cout << std::boolalpha << is_all_pointer::value << "\n";
using almost_all_pointer = all< std::is_pointer, char*, void**, long, float****>;
std::cout << std::boolalpha << almost_all_pointer::value << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment