Program listing for file kernel/src/utils/SiconosTools/VisitorMaker.hpp#
Return to documentation for this file
1#ifndef VisitorMaker_hpp
2#define VisitorMaker_hpp
3
4#include <SiconosVisitor.hpp>
5#include <boost/type_traits.hpp>
6#include <boost/mpl/if.hpp>
7#include <boost/mpl/vector.hpp>
8#include <boost/mpl/fold.hpp>
9
10
11
12
13namespace Experimental {
14
15 struct TypeNotFound {};
16
17
18 template<typename T, typename Action, typename BaseType>
19 struct Call : public Action
20 {
21 typedef Call<T, Action, BaseType> type;
22
23 using Action::visit;
24
25 virtual void visit(const T& x)
26 {
27 (*this)(static_cast<const BaseType&>(x));
28 }
29 };
30
31
32 template<typename T, typename Action>
33 struct Call<T, Action, TypeNotFound> : public Action
34 {
35 typedef Call<T, Action, TypeNotFound> type;
36
37 using Action::visit;
38
39 virtual void visit(const T& x)
40 {
41 }
42 };
43
44
45 template<typename T, typename Pred>
46 class VisitMaker
47 {
48 private:
49 typedef typename
50 boost::mpl::fold<
51 typename Pred::Action::Base,
52 TypeNotFound,
53 boost::mpl::if_<boost::is_base_of<boost::mpl::_2, T>,
54 boost::mpl::_2,
55 boost::mpl::_1> >::type BaseType;
56
57 public:
58
59 typedef typename Call<T, typename Pred::Action, BaseType>::type Action;
60 };
61
62
63#undef REGISTER
64#undef REGISTER_STRUCT
65#undef REGISTER_BASE
66#undef REGISTER_BASE_EXTERN
67
68#define REGISTER(X) VisitMaker<X,
69#define REGISTER_STRUCT(X)
70#define REGISTER_BASE(X, Y) REGISTER(X)
71#define REGISTER_BASE_EXTERN(X, Y)
72
73 template<typename T>
74 struct GlobalVisitor
75 {
76 typedef typename
77 VISITOR_CLASSES()
78 T
79
80#undef REGISTER
81#undef REGISTER_STRUCT
82#undef REGISTER_BASE
83#undef REGISTER_BASE_EXTERN
84
85#define REGISTER(X) >
86#define REGISTER_STRUCT(X)
87#define REGISTER_BASE(X, Y) REGISTER(X)
88#define REGISTER_BASE_EXTERN(X, Y)
89 VISITOR_CLASSES()
90 ::Action Make;
91 };
92
93
94
95 struct empty{};
96
97 template<typename T1 = empty, typename T2 = empty, typename T3 = empty,
98 typename T4 = empty, typename T5 = empty, typename T6 = empty,
99 typename T7 = empty, typename T8 = empty, typename T9 = empty>
100 struct Classes
101 {
102 typedef typename boost::mpl::vector<T1, T2, T3, T4, T5, T6, T7, T8, T9> Base;
103 };
104
105 template<typename T1>
106 struct Classes<T1, empty, empty, empty, empty, empty, empty, empty, empty>
107 {
108 typedef typename boost::mpl::vector<T1> Base;
109 };
110
111 template<typename T1, typename T2>
112 struct Classes<T1, T2, empty, empty, empty, empty, empty, empty, empty>
113 {
114 typedef typename boost::mpl::vector<T1, T2> Base;
115 };
116
117 template<typename T1, typename T2, typename T3>
118 struct Classes<T1, T2, T3, empty, empty, empty, empty, empty, empty>
119 {
120 typedef typename boost::mpl::vector<T1, T2, T3> Base;
121 };
122
123 template<typename T1, typename T2, typename T3, typename T4>
124 struct Classes<T1, T2, T3, T4, empty, empty, empty, empty, empty>
125 {
126 typedef typename boost::mpl::vector<T1, T2, T3, T4> Base;
127 };
128
129 template<typename T1, typename T2, typename T3, typename T4, typename T5>
130 struct Classes<T1, T2, T3, T4, T5, empty, empty, empty, empty>
131{
132 typedef typename boost::mpl::vector<T1, T2, T3, T4, T5> Base;
133 };
134
135 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
136 struct Classes<T1, T2, T3, T4, T5, T6, empty, empty, empty>
137 {
138 typedef typename boost::mpl::vector<T1, T2, T3, T4, T5, T6> Base;
139 };
140
141 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
142 struct Classes<T1, T2, T3, T4, T5, T6, T7, empty, empty>
143 {
144 typedef typename boost::mpl::vector<T1, T2, T3, T4, T5, T6, T7> Base;
145 };
146
147 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
148 struct Classes<T1, T2, T3, T4, T5, T6, T7, T8, empty>
149 {
150 typedef typename boost::mpl::vector<T1, T2, T3, T4, T5, T6, T7, T8> Base;
151 };
152
153
154 template<typename C, typename T>
155 struct Filter
156 {
157 struct _T : public T, public C
158 {
159 typedef _T Action;
160 };
161
162 typedef typename
163 boost::mpl::fold<
164 typename C::Base,
165 _T,
166 VisitMaker<boost::mpl::_2, boost::mpl::_1 >
167 >::type Make;
168 };
169
170 template<typename C, typename T>
171 struct Visitor
172 {
173 typedef typename Filter<C, T>::Make LocalFilter;
174
175 typedef typename GlobalVisitor<LocalFilter>::Make Make;
176
177 };
178
179}
180
181#endif