2017-07-05 3 views
3

Yat-il un concis façon d'obtenir une séquence d'indices d'éléments de tuples qui satisfont un prédicat à Hana?Séquence d'indices d'éléments de tuple satifying prédicat dans Hana

Voici le code que j'ai écrit pour cela en utilisant seulement la bibliothèque standard:

template <template<typename> typename Pred, typename Tuple> 
class get_indices_of { 
    static constexpr size_t size = std::tuple_size<Tuple>::value; 
    template <size_t I, size_t... II> struct impl { 
    using type = std::conditional_t< 
     Pred<std::tuple_element_t<I,Tuple>>::value, 
     typename impl<I+1, II..., I>::type, 
     typename impl<I+1, II...>::type >; 
    }; 
    template <size_t... II> struct impl<size,II...> { 
    using type = std::index_sequence<II...>; 
    }; 
public: 
    using type = typename impl<0>::type; 
}; 
template <template<typename> typename Pred, typename Tuple> 
using get_indices_of_t = typename get_indices_of<Pred,Tuple>::type; 

Exemple d'utilisation:

using types = std::tuple<std::string,int,double,char>; 
using ints = get_indices_of_t<std::is_integral,types>; 

Le type de ints est maintenant std::index_sequence<1ul, 3ul>.

+0

Quel est le problème avec votre code? De toute façon, ça va être envoyé dans un en-tête de bibliothèque, alors on s'en fout si c'est un peu compliqué. J'ai quelques idées sur la façon dont cela pourrait être fait différemment, mais sans savoir quel est le problème avec votre approche actuelle, il est difficile de savoir ce qui serait le mieux. – Frank

+0

Il n'y a pas de problème avec mon code. Je l'ai posté comme une explication de ce que je veux faire. Je veux juste savoir si Hana a un algorithme pour ça. – SU3

Répondre

2

Je suppose quelque chose comme ceci:

constexpr auto get_indices_of = [](auto tuple, auto predicate){ 
    constexpr auto indices = to<tuple_tag>(range_c<std::size_t, 0, size(tuple)>); 
    return filter(indices, [=](auto i){ return predicate(tuple[i]); }); 
}; 

La seule partie délicate, il obtient les indices, puisque range_c lui-même est pas un MonadPlus. Votre exemple réel, en utilisant cette fonction, est:

constexpr auto types = make_tuple(
    type_c<std::string>, type_c<int>, type_c<double>, type_c<char>); 
constexpr auto ints = get_indices_of(types, trait<std::is_integral>); 
+2

Des chats et des chiens répondant à des questions de métaprogrammation - Hystérie de masse! BTW il ya aussi une demande ouverte pour cette fonctionnalité https://github.com/boostorg/hana/issues/273 –

+1

Techniquement, la raison pour laquelle vous avez besoin de ' (range_c <...>)' est parce que 'range_c' n'est pas un' MonadPlus' (voir [this] (http://boostorg.github.io/hana/group__group-MonadPlus.html)), pas parce que ce n'est pas une 'Sequence'. Ceci est juste un nitpick, et votre réponse est par ailleurs correcte. –

+0

@LouisDionne Doit être en utilisant une vieille traction de hana, je jure l'assertion statique a déclaré qu'il devait être une séquence - dit définitivement MonadPlus. Woops. – Barry