Created
April 29, 2016 14:48
-
-
Save jfalcou/73ac092884f6e8136212f1433db73ee1 to your computer and use it in GitHub Desktop.
C++ FRUG 07/04/2016
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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