|
16 | 16 | #include <iris/x4/core/unused.hpp> |
17 | 17 | #include <iris/x4/core/parser_traits.hpp> |
18 | 18 |
|
| 19 | +#include <iris/type_traits.hpp> // TODO: move iris::type_list to separate header |
| 20 | + |
19 | 21 | #include <type_traits> |
20 | 22 |
|
21 | 23 | namespace iris::x4::traits { |
22 | 24 |
|
23 | 25 | namespace detail { |
24 | 26 |
|
25 | | -template<class... Ts> |
26 | | -struct type_sequence |
27 | | -{ |
28 | | - using type = type_sequence; |
29 | | - |
30 | | - static constexpr std::size_t size = sizeof...(Ts); |
31 | | - |
32 | | - template<class... Us> |
33 | | - using prepend = type_sequence<Us..., Ts...>; |
| 27 | +template<class TypeList, class... Us> |
| 28 | +struct append_to_type_list {}; |
34 | 29 |
|
35 | | - template<class U> |
36 | | - using extend = U::template prepend<Ts...>; |
| 30 | +template<class TypeList, class... Us> |
| 31 | +using append_to_type_list_t = append_to_type_list<TypeList, Us...>::type; |
37 | 32 |
|
38 | | - template<template<class...> class U> |
39 | | - using transfer_to = U<Ts...>; |
| 33 | +template<class... Ts> |
| 34 | +struct append_to_type_list<type_list<Ts...>> |
| 35 | +{ |
| 36 | + using type = type_list<Ts...>; |
40 | 37 | }; |
41 | 38 |
|
42 | | -template<X4Attribute Attr> |
43 | | -struct types_of_binary_init : type_sequence<Attr> |
| 39 | +template<class... Ts, class... Us> |
| 40 | +struct append_to_type_list<type_list<Ts...>, unused_type, Us...> |
| 41 | + : append_to_type_list<type_list<Ts...>, Us...> |
44 | 42 | {}; |
45 | 43 |
|
46 | | -template<> |
47 | | -struct types_of_binary_init<unused_type> : type_sequence<> |
| 44 | +template<class... Ts, class U, class... Us> |
| 45 | +struct append_to_type_list<type_list<Ts...>, U, Us...> |
| 46 | + : append_to_type_list<type_list<Ts..., U>, Us...> |
48 | 47 | {}; |
49 | 48 |
|
50 | | -template<> |
51 | | -struct types_of_binary_init<unused_type const> : type_sequence<> |
| 49 | +template<class... Ts, class... Us, class... Vs> |
| 50 | +struct append_to_type_list<type_list<Ts...>, type_list<Us...>, Vs...> |
| 51 | + : append_to_type_list<append_to_type_list_t<type_list<Ts...>, Us...>, Vs...> |
52 | 52 | {}; |
53 | 53 |
|
54 | | -template<template<class, class> class BinaryParserTT, class ParserT> |
55 | | -struct get_types_of_binary |
56 | | - : types_of_binary_init<typename parser_traits<ParserT>::attribute_type> // TODO: unwrap |
57 | | -{}; |
| 54 | +template<template<class...> class TupleTT, class T> |
| 55 | +struct tuple_to_type_list; |
58 | 56 |
|
59 | | -template<template<class, class> class BinaryParserTT, class Left, class Right> |
60 | | -struct get_types_of_binary<BinaryParserTT, BinaryParserTT<Left, Right>> |
61 | | - : get_types_of_binary<BinaryParserTT, Left>::template extend<get_types_of_binary<BinaryParserTT, Right>> |
62 | | -{}; |
| 57 | +template<template<class...> class TupleTT, class T> |
| 58 | +using tuple_to_type_list_t = tuple_to_type_list<TupleTT, T>::type; |
63 | 59 |
|
64 | | -template<template<class...> class AttrTT, class T, std::size_t = T::size> |
65 | | -struct type_sequence_to_attribute |
| 60 | +template<template<class...> class TupleTT, class T> |
| 61 | +struct tuple_to_type_list |
66 | 62 | { |
67 | | - using type = typename T::template transfer_to<AttrTT>; |
| 63 | + using type = T; |
68 | 64 | }; |
69 | 65 |
|
70 | | -template<template<class...> class AttrTT, class T> |
71 | | -struct type_sequence_to_attribute<AttrTT, T, 1> |
72 | | - : T::template transfer_to<std::type_identity> |
73 | | -{}; |
| 66 | +template<template<class...> class TupleTT, class... Ts> |
| 67 | +struct tuple_to_type_list<TupleTT, TupleTT<Ts...>> |
| 68 | +{ |
| 69 | + using type = type_list<tuple_to_type_list_t<TupleTT, Ts>...>; |
| 70 | +}; |
| 71 | + |
| 72 | +template<template<class...> class TupleTT, class T> |
| 73 | +using tuple_to_type_list_t = tuple_to_type_list<TupleTT, T>::type; |
| 74 | + |
| 75 | +template<template<class...> class TupleTT, class TypeList> |
| 76 | +struct type_list_to_tuple {}; |
74 | 77 |
|
75 | | -template<template<class...> class AttrTT, class T> |
76 | | -struct type_sequence_to_attribute<AttrTT, T, 0> |
| 78 | +template<template<class...> class TupleTT> |
| 79 | +struct type_list_to_tuple<TupleTT, type_list<>> |
77 | 80 | { |
78 | 81 | using type = unused_type; |
79 | 82 | }; |
80 | 83 |
|
| 84 | +template<template<class...> class TupleTT, class T> |
| 85 | +struct type_list_to_tuple<TupleTT, type_list<T>> |
| 86 | +{ |
| 87 | + using type = T; |
| 88 | +}; |
| 89 | + |
| 90 | +template<template<class...> class TupleTT, class T0, class T1, class... Ts> |
| 91 | +struct type_list_to_tuple<TupleTT, type_list<T0, T1, Ts...>> |
| 92 | +{ |
| 93 | + using type = TupleTT<T0, T1, Ts...>; |
| 94 | +}; |
| 95 | + |
| 96 | +template<template<class...> class TupleTT, class TypeList> |
| 97 | +using type_list_to_tuple_t = type_list_to_tuple<TupleTT, TypeList>::type; |
| 98 | + |
81 | 99 | } // detail |
82 | 100 |
|
83 | 101 | template< |
84 | | - template<class...> class AttrTT, |
85 | | - template<class, class> class BinaryParserTT, |
86 | | - class Left, class Right |
| 102 | + template<class...> class TupleTT, |
| 103 | + class LeftParser, class RightParser |
87 | 104 | > |
88 | 105 | struct attribute_of_binary |
89 | 106 | { |
90 | | - using type = detail::type_sequence_to_attribute< |
91 | | - AttrTT, |
92 | | - typename detail::get_types_of_binary<BinaryParserTT, BinaryParserTT<Left, Right>>::type |
93 | | - >::type; |
| 107 | + using type = detail::type_list_to_tuple_t< |
| 108 | + TupleTT, |
| 109 | + detail::append_to_type_list_t< |
| 110 | + type_list<>, |
| 111 | + detail::tuple_to_type_list_t<TupleTT, typename parser_traits<LeftParser>::attribute_type>, |
| 112 | + detail::tuple_to_type_list_t<TupleTT, typename parser_traits<RightParser>::attribute_type> |
| 113 | + > |
| 114 | + >; |
94 | 115 | }; |
95 | 116 |
|
96 | 117 | } // iris::x4::traits |
|
0 commit comments