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++
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.