state_machine_cpp
merge.h
Go to the documentation of this file.
1 //
2 // Created by henri on 10/11/21.
3 //
4 
5 #ifndef STATE_MACHINE_CPP_MERGE_H
6 #define STATE_MACHINE_CPP_MERGE_H
7 
8 
9 #include <cassert>
11 
12 namespace state_machine_cpp {
13  class AbstractLayer;
14 
15  template<class ...> class AttributeTree;
16 
17  template<class ...> class Layer;
18 }
19 
21 
22 namespace state_machine_cpp::Impl {
23 
24  template<class ...>
25  struct merge_layers;
26 
27  template<class ...X, class ...Y>
28  struct merge_layers<Layer<X...>, Layer<Y...>> {
29  using type = Layer<X..., Y...>;
30  };
31 
32  template<class ...>
33  struct merge_t;
34 
35  template<class A>
37  using type = A;
38  };
39 
40  template<class ...A, class HX, class ...QX>
41  struct merge_t<AttributeTree<A...>, AttributeTree<HX, QX...>, AttributeTree<>> {
42  using type = typename merge_t<
43  AttributeTree<A..., HX>,
44  AttributeTree<QX...>,
47  };
48 
49  template<class ...A, class HY, class ...QY>
50  struct merge_t<AttributeTree<A...>, AttributeTree<>, AttributeTree<HY, QY...>> {
51  using type = typename merge_t<
52  AttributeTree<A..., HY>,
54  AttributeTree<QY...>
56  };
57 
58  template<class ...A, class HX, class ...QX, class HY, class ...QY>
59  struct merge_t<AttributeTree<A...>, AttributeTree<HX, QX...>, AttributeTree<HY, QY...>> {
60  using type = typename merge_t<
62  AttributeTree<QX...>,
63  AttributeTree<QY...>
65  };
66 
68 
69  template<class ...X> struct merge;
70 
71  template<class ...> struct call_merge;
72 
73  template<class HY, class ...QY>
74  struct call_merge<Layer<HY, QY...>> {
75 
76  static void on(Layer<>*, AbstractLayer&) {
77  assert(false);
78  }
79 
80  static void on(Layer<HY, QY...>* t_layer, AbstractLayer& t_destination) {
81  merge<std::tuple<HY, QY...>, Layer<HY, QY...>>::to(t_layer, t_destination);
82  }
83 
84  };
85 
86  template<class ...X>
87  struct merge<std::tuple<>, AttributeTree<X...>> {
88 
89  static void to(AttributeTree<X...>* t_source, AbstractAttributeTree& t_destination, unsigned int t_layer = 0) {}
90 
91  };
92 
93  template<class HX, class ...QX, class ...X>
94  struct merge<std::tuple<HX, QX...>, AttributeTree<X...>> {
95 
96  static void to(AttributeTree<X...>* t_source, AbstractAttributeTree& t_destination, unsigned int t_layer = 0) {
97  if constexpr (!std::is_same_v<HX, Layer<>>) {
98  auto &layer = dynamic_cast<HX &>(((AbstractAttributeTree *) t_source)->layer(t_layer));
99  call_merge<HX>::on(&layer, t_destination.layer(t_layer));
100  }
101  merge<std::tuple<QX...>, AttributeTree<X...>>::to(t_source, t_destination, t_layer + 1);
102  }
103 
104  };
105 
106  template<class ...X>
107  struct merge<std::tuple<>, Layer<X...>> {
108 
109  static void to(Layer<X...>* t_source, AbstractLayer& t_destination) {}
110 
111  };
112 
113  template<class HX, class ...QX, class ...X>
114  struct merge<std::tuple<HX, QX...>, Layer<X...>> {
115 
116  static void to(Layer<X...>* t_source, AbstractLayer& t_destination) {
117  dynamic_cast<std::shared_ptr<HX>&>(t_destination).swap(dynamic_cast<std::shared_ptr<HX>&>(*t_source));
118  merge<std::tuple<QX...>, Layer<X...>>::to(t_source, t_destination);
119  }
120 
121  };
122 
123 }
124 
125 namespace state_machine_cpp {
126 
127  template<class ...T> using merge_t = typename Impl::merge_t<AttributeTree<>, T...>::type;
128 
129 }
130 
131 
132 #endif //STATE_MACHINE_CPP_MERGE_H
state_machine_cpp::Impl::merge< std::tuple<>, Layer< X... > >::to
static void to(Layer< X... > *t_source, AbstractLayer &t_destination)
Definition: merge.h:109
state_machine_cpp::Impl::merge< std::tuple< HX, QX... >, AttributeTree< X... > >::to
static void to(AttributeTree< X... > *t_source, AbstractAttributeTree &t_destination, unsigned int t_layer=0)
Definition: merge.h:96
state_machine_cpp::Layer<>
Definition: layer.h:25
state_machine_cpp::Impl::call_merge< Layer< HY, QY... > >::on
static void on(Layer< HY, QY... > *t_layer, AbstractLayer &t_destination)
Definition: merge.h:80
state_machine_cpp::Impl::merge_t< AttributeTree< A... >, AttributeTree<>, AttributeTree< HY, QY... > >::type
typename merge_t< AttributeTree< A..., HY >, AttributeTree<>, AttributeTree< QY... > >::type type
Definition: merge.h:55
state_machine_cpp::AbstractAttributeTree
Definition: abstract_attribute_tree.h:17
state_machine_cpp::Impl::merge_t
Definition: merge.h:33
state_machine_cpp::Impl::call_merge
Definition: merge.h:71
state_machine_cpp::Impl::merge_layers
Definition: merge.h:25
state_machine_cpp
Definition: algorithm.h:14
state_machine_cpp::Impl::merge< std::tuple< HX, QX... >, Layer< X... > >::to
static void to(Layer< X... > *t_source, AbstractLayer &t_destination)
Definition: merge.h:116
state_machine_cpp::Impl::merge< std::tuple<>, AttributeTree< X... > >::to
static void to(AttributeTree< X... > *t_source, AbstractAttributeTree &t_destination, unsigned int t_layer=0)
Definition: merge.h:89
state_machine_cpp::Impl::merge_t< A, AttributeTree<>, AttributeTree<> >::type
A type
Definition: merge.h:37
state_machine_cpp::AbstractLayer
Definition: abstract_layer.h:12
state_machine_cpp::Impl::merge_t< AttributeTree< A... >, AttributeTree< HX, QX... >, AttributeTree<> >::type
typename merge_t< AttributeTree< A..., HX >, AttributeTree< QX... >, AttributeTree<> >::type type
Definition: merge.h:46
state_machine_cpp::Impl::merge
Definition: abstract_attribute_tree.h:13
state_machine_cpp::merge_t
typename Impl::merge_t< AttributeTree<>, T... >::type merge_t
Definition: merge.h:127
state_machine_cpp::AttributeTree
Definition: attribute_tree.h:15
state_machine_cpp::Impl
Definition: abstract_attribute_tree.h:12
state_machine_cpp::Impl::merge_t< AttributeTree< A... >, AttributeTree< HX, QX... >, AttributeTree< HY, QY... > >::type
typename merge_t< AttributeTree< A..., typename merge_layers< HX, HY >::type >, AttributeTree< QX... >, AttributeTree< QY... > >::type type
Definition: merge.h:64
state_machine_cpp::Layer
Definition: layer.h:12
state_machine_cpp::Impl::call_merge< Layer< HY, QY... > >::on
static void on(Layer<> *, AbstractLayer &)
Definition: merge.h:76
abstract_attribute_tree.h
state_machine_cpp::AbstractAttributeTree::layer
virtual AbstractLayer & layer(unsigned int t_i)=0