Partage
  • Partager sur Facebook
  • Partager sur Twitter

Linéarisation variadique d'une expression template

    11 mai 2018 à 14:36:34

    Salut,

    Le but est d'obtenir `result<fields<F2>, tables<T2, T3>, size<3> >` depuis une expression template en utilisant des variadiques àa la place de la liste de using dans result.

    Voici le code :

    #include <iostream>
    #include <cxxabi.h>
    #include <tuple>
     
    struct op_value;
    struct op_field;
    struct op_table;
    struct op_and;
     
    template<class> struct field { using table = void; };
    template<class> struct table;
    template<int N> struct size { static constexpr auto value = N; };
     
    template<class T>
    struct param;
     
    struct void_
    {
        using linearize = void;
    };
     
    template<class...>
    struct fields{};
     
    template<class T, class... Ts>
    struct fields<field<T>, fields<Ts...>>
    {
        using pack = fields<T, Ts...>;
    };
    template<class... T, class... Ts>
    struct fields<fields<T...>, fields<Ts...>>
    {
        using pack = fields<T..., Ts...>;
    };
     
    template<class... Ts>
    struct tables { };
     
    template<class T, class... Ts>
    struct tables<table<T>, tables<Ts...>>
    {
        using pack = tables<T, Ts...>;
    };
    template<class... Ts>
    struct tables<void, tables<Ts...>>
    {
        using pack = tables<Ts...>;
    };
     
    template<class... T, class... Ts>
    struct tables<tables<T...>, tables<Ts...>>
    {
        using pack = tables<T..., Ts...>;
    };
     
    //
    template<class Fs, class Ts, class S>
    struct result
    {
        using linearize = result<Fs, Ts, S>;
     
        using Fields = Fs;
        using Tables = Ts;
        using Size = S;
    };
     
     
    template<class L, class R, class S>
    struct result<field<L>, table<R>, S>
    {
        using Fields = fields<L>;
        using Tables = tables<R>;
     
        using linearize = result<fields<L>, tables<R, typename L::table>, size<S::value + R::size::value + L::size::value>>;
    };
     
     
    template<class L, class S, class... R>
    struct result<table<L>, result<R...>, S>
    {
        using Fields = typename result<R...>::Fields;
        using Tables = typename tables<table<L>, typename result<R...>::Tables>::pack;
        using linearize = result<Fields, Tables, size<5>>;
    };
     
     
    template<class L, class S, class... R>
    struct result<field<L>, result<R...>, S>
    {
        using Fields = typename fields<field<L>, typename result<R...>::Fields>::pack;
        using Tables = typename tables<typename field<L>::table, typename result<R...>::Tables>::pack;
        using linearize = result<Fields, Tables, size<5>>;
    };
     
     
    template<class S, class... L, class... R>
    struct result<result<L...>, result<R...>, S>
    {
        using Fields = typename fields<typename result<L...>::Fields, typename result<R...>::Fields>::pack;
        using Tables = typename tables<typename result<L...>::Tables, typename result<R...>::Tables>::pack;
        using linearize = result<Fields, Tables, size<5>>;
    };
     
     
    struct T {using size = ::size<1>; using linearize = table<T>; };
    struct T2 {using size = ::size<1>; using linearize = table<T2>; };
    struct T3 {using size = ::size<1>; using linearize = table<T3>; };
     
    struct F{  using size = ::size<2>; using linearize = field<F>; using table = T; };
    struct F2 { using size = ::size<2>; using linearize = field<F2>; using table = T3; };
     
    template<class L, class T = op_value, class R = void_>
    struct expr
    {
        using linearize = typename result<typename L::linearize, typename R::linearize, size<0>>::linearize;
    };
     
    template<class L>
    struct expr<L, op_field, void_>
    {
        using linearize = field<L>;
    };
     
    template<class L>
    struct expr<L, op_table, void_>
    {
        using linearize = table<L>;
    };
     
     
    int main()
    {
        using Expr_F_T =
        expr<
            expr<F2, op_field>,
                op_and,
            expr<T2, op_table>
        >;
         
        using Linearized = typename Expr_F_T::linearize;
     
        auto realname = abi::__cxa_demangle(typeid(Linearized).name(), 0, 0, 0);
        std::cout << realname;
     
        std::cout << "\n_" << Linearized::Size::value;
         
        return 0;
    }

    L'idée c'est de pouvoir créer un type custom qui ressemblerait à une structure c++

    Merci !

    -
    Edité par ads00 14 juin 2018 à 7:15:15

    • Partager sur Facebook
    • Partager sur Twitter
      13 juin 2018 à 19:56:41

      Quelqu'un a une idée pour rendre ça plus générique ? Actuellement à chaque ajout de "champs" pour le résultat, ça demande pas mal de répétitions.
      • Partager sur Facebook
      • Partager sur Twitter

      Linéarisation variadique d'une expression template

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown