Ariles
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
common.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2017-2020 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @brief
9 */
10 // cppcheck-suppress-file duplInheritedMember
11 
12 #pragma once
13 
14 #include <utility>
15 #include <vector>
16 #include <string_view>
17 #include "../internal/helpers.h"
18 
19 namespace ariles2
20 {
21  namespace visitor
22  {
23  class Parameters
24  {
25  public:
27 
28  public:
29  explicit Parameters(const bool override_parameters = true)
30  {
31  override_parameters_ = override_parameters;
32  }
33  };
34 
35 
36  class Visitor
37  {
38  protected:
39  Visitor(){};
40  ~Visitor(){};
41  };
42 
43 
44  template <class t_Derived, class t_Parameters, class t_ReturnType = void>
45  class Base : public Visitor
46  {
47  public:
48  using ReturnType = t_ReturnType;
50 
51  public:
52  virtual const t_Parameters &getDefaultParameters() const
53  {
54  const static t_Parameters parameters(false);
55  return parameters;
56  }
57 
58  // cppcheck-suppress duplInheritedMember
59  template <class t_Ariles>
60  const t_Parameters &getParameters(const t_Ariles &ariles_class) const
61  {
62  return (ariles_class.arilesGetParameters(*static_cast<const t_Derived *>(this)));
63  }
64  };
65  } // namespace visitor
66 
67 
68 #define ARILES2_BASE_METHODS(Namespace) \
69  using Namespace::Base::arilesVirtualVisit; \
70  using Namespace::Base::arilesGetParameters;
71 
72 #define ARILES2_METHODS(Namespace, VisitorQualifier, MethodQualifier) \
73  void arilesVirtualVisit( \
74  VisitorQualifier ariles2::Namespace::Visitor &visitor, \
75  const ariles2::Namespace::Visitor::Parameters &param) MethodQualifier override \
76  { \
77  CPPUT_TRACE_FUNCTION; \
78  this->arilesVisit(visitor, param); \
79  } \
80  using ariles2::Namespace::Base::arilesGetParameters;
81 
82 
83  namespace entry
84  {
85  template <class t_Visitor>
86  class Base
87  {
88  public:
89  virtual typename t_Visitor::ReturnType arilesVirtualVisit(
90  t_Visitor &,
91  const typename t_Visitor::Parameters &) = 0;
92 
93  virtual const typename t_Visitor::Parameters &arilesGetParameters(const t_Visitor &visitor) const
94  {
96  return (visitor.getDefaultParameters());
97  }
98  };
99 
100 
101  template <class t_Visitor>
102  class ConstBase
103  {
104  public:
105  virtual typename t_Visitor::ReturnType arilesVirtualVisit(
106  t_Visitor &,
107  const typename t_Visitor::Parameters &) const = 0;
108 
109  virtual const typename t_Visitor::Parameters &arilesGetParameters(const t_Visitor &visitor) const
110  {
112  return (visitor.getDefaultParameters());
113  }
114  };
115  } // namespace entry
116 
117  namespace traits
118  {
119  template <class t_Subtree>
120  using is_subtree = std::disjunction<
121  std::is_same<std::string, std::decay_t<t_Subtree>>, //
122  std::is_same<char *, std::decay_t<t_Subtree>>, //
123  std::is_same<const char *, std::decay_t<t_Subtree>>, //
124  std::is_same<std::string_view, std::decay_t<t_Subtree>>, //
125  std::is_same<std::vector<std::string>, std::decay_t<t_Subtree>>>;
126 
127  template <class t_Subtree>
128  using is_subtree_t = std::enable_if_t<is_subtree<t_Subtree>::value>;
129 
130  template <class t_Subtree>
131  using is_not_subtree_t = std::enable_if_t<not is_subtree<t_Subtree>::value>;
132 
133 
134  template <class t_Visitor>
135  using is_visitor_t = std::enable_if_t<std::is_base_of_v<ariles2::visitor::Visitor, t_Visitor>>;
136 
137  template <class t_Visitor>
138  using is_not_visitor_t = std::enable_if_t<not std::is_base_of_v<ariles2::visitor::Visitor, t_Visitor>>;
139 
140  template <class t_Ariles>
141  using is_ariles_t = std::enable_if_t<std::is_base_of_v<ariles2::Ariles, t_Ariles>>;
142 
143  template <class t_Ariles>
144  using is_not_ariles_t = std::enable_if_t<not std::is_base_of_v<ariles2::Ariles, t_Ariles>>;
145  } // namespace traits
146 } // namespace ariles2
147 
148 #ifndef ARILES2_DISABLE
149 # ifndef ARILES2_ENABLED
150 # define ARILES2_ENABLED
151 # endif
152 #endif
153 
154 #ifdef ARILES2_ENABLED
155 
156 namespace ariles2
157 {
158  // -----
159  template <
160  class t_Ariles,
161  class t_Visitor,
162  class t_Subtree,
163  typename = traits::is_subtree_t<t_Subtree>,
164  typename = traits::is_visitor_t<t_Visitor>>
165  typename t_Visitor::ReturnType apply(
166  t_Visitor &visitor,
167  t_Ariles &ariles_class,
168  t_Subtree &&subtree,
169  const typename t_Visitor::Parameters &param)
170  {
172  return (visitor.visit(ariles_class, std::forward<t_Subtree>(subtree), param));
173  }
174 
175 
176  template <class t_Visitor, class t_Ariles, typename = traits::is_visitor_t<t_Visitor>>
177  typename t_Visitor::ReturnType apply(
178  t_Visitor &visitor,
179  t_Ariles &ariles_class,
180  const typename t_Visitor::Parameters &param)
181  {
183  return (visitor.visit(ariles_class, ariles_class.arilesDefaultID(), param));
184  }
185 
186 
187  template <
188  class t_Visitor,
189  class t_Ariles,
190  class t_Subtree,
191  typename = traits::is_subtree_t<t_Subtree>,
192  typename = traits::is_visitor_t<t_Visitor>>
193  typename t_Visitor::ReturnType apply(t_Visitor &visitor, t_Ariles &ariles_class, t_Subtree &&subtree)
194  {
196  return (visitor.visit(ariles_class, std::forward<t_Subtree>(subtree), visitor.getParameters(ariles_class)));
197  }
198 
199 
200  template <class t_Visitor, class t_Ariles, typename = traits::is_visitor_t<t_Visitor>>
201  typename t_Visitor::ReturnType apply(t_Visitor &visitor, t_Ariles &ariles_class)
202  {
204  return (ariles2::apply(visitor, ariles_class, ariles_class.arilesDefaultID()));
205  }
206 
207 
208  template <
209  class t_Visitor,
210  class t_Ariles,
211  typename = traits::is_visitor_t<t_Visitor>,
212  typename = traits::is_ariles_t<t_Ariles>>
213  typename t_Visitor::ReturnType apply(t_Ariles &ariles_class)
214  {
216  t_Visitor visitor;
217  return (ariles2::apply(visitor, ariles_class));
218  }
219  // -----
220 
221 
222 
223  // -----
224  template <
225  class t_Visitor,
226  typename t_Arg,
227  typename... t_Args,
228  typename = traits::is_not_visitor_t<t_Arg>,
229  typename = traits::is_not_ariles_t<t_Arg>>
230  typename t_Visitor::ReturnType apply(t_Arg &&arg, t_Args &&...args)
231  {
233  t_Visitor visitor(std::forward<t_Arg>(arg));
234  return (ariles2::apply(visitor, std::forward<t_Args>(args)...));
235  }
236  // -----
237 
238 
239  // -----
240  template <
241  class t_Visitor,
242  class t_Left,
243  class t_Right,
244  typename = traits::is_visitor_t<t_Visitor>,
245  typename = traits::is_ariles_t<t_Left>,
246  typename = traits::is_not_subtree_t<t_Right>>
247  typename t_Visitor::ReturnType apply(t_Left &left, t_Right &right)
248  {
250  t_Visitor visitor;
251  return (visitor.visit(left, right, left.arilesDefaultID(), visitor.getParameters(left)));
252  }
253 
254 
255  template <
256  class t_Visitor,
257  class t_Left,
258  class t_Right,
259  typename = traits::is_not_subtree_t<t_Right>,
260  typename = traits::is_visitor_t<t_Visitor>>
261  typename t_Visitor::ReturnType apply(
262  t_Visitor &visitor,
263  t_Left &left,
264  t_Right &right,
265  const std::string &name,
266  const typename t_Visitor::Parameters &param)
267  {
269  return (visitor.visit(left, right, name, param));
270  }
271 
272 
273  template <
274  class t_Visitor,
275  class t_Left,
276  class t_Right,
277  typename = traits::is_visitor_t<t_Visitor>,
278  typename = traits::is_not_subtree_t<t_Right>,
279  typename = std::enable_if_t<not std::is_base_of_v<typename t_Visitor::Parameters, t_Right>>>
280  typename t_Visitor::ReturnType apply(t_Visitor &visitor, t_Left &left, t_Right &right)
281  {
283  return (visitor.visit(left, right, left.arilesDefaultID(), visitor.getParameters(left)));
284  }
285 
286 
287  template <
288  class t_Visitor,
289  class t_Left,
290  class t_Right,
291  typename = traits::is_not_subtree_t<t_Right>,
292  typename = traits::is_visitor_t<t_Visitor>>
293  typename t_Visitor::ReturnType apply(
294  t_Visitor &visitor,
295  t_Left &left,
296  t_Right &right,
297  const typename t_Visitor::Parameters &param)
298  {
300  return (ariles2::apply(visitor, left, right, left.arilesDefaultID(), param));
301  }
302  // -----
303 } // namespace ariles2
304 
305 #else
306 
307 namespace ariles2
308 {
309  template <class t_Visitor, class... t_Args>
310  void apply(t_Args &&.../*args*/)
311  {
312  }
313 
314  template <class... t_Args>
315  void apply(t_Args &&.../*args*/)
316  {
317  }
318 } // namespace ariles2
319 
320 #endif
virtual const t_Visitor::Parameters & arilesGetParameters(const t_Visitor &visitor) const
Definition: common.h:93
virtual t_Visitor::ReturnType arilesVirtualVisit(t_Visitor &, const typename t_Visitor::Parameters &)=0
virtual const t_Visitor::Parameters & arilesGetParameters(const t_Visitor &visitor) const
Definition: common.h:109
virtual t_Visitor::ReturnType arilesVirtualVisit(t_Visitor &, const typename t_Visitor::Parameters &) const =0
virtual const t_Parameters & getDefaultParameters() const
Definition: common.h:52
const t_Parameters & getParameters(const t_Ariles &ariles_class) const
Definition: common.h:60
t_ReturnType ReturnType
Definition: common.h:48
Parameters(const bool override_parameters=true)
Definition: common.h:29
visitor::Parameters Parameters
Definition: count.h:26
std::enable_if_t< std::is_base_of_v< ariles2::visitor::Visitor, t_Visitor > > is_visitor_t
Definition: common.h:135
std::enable_if_t< is_subtree< t_Subtree >::value > is_subtree_t
Definition: common.h:128
std::enable_if_t< not std::is_base_of_v< ariles2::Ariles, t_Ariles > > is_not_ariles_t
Definition: common.h:144
std::enable_if_t< std::is_base_of_v< ariles2::Ariles, t_Ariles > > is_ariles_t
Definition: common.h:141
std::disjunction< std::is_same< std::string, std::decay_t< t_Subtree > >, std::is_same< char *, std::decay_t< t_Subtree > >, std::is_same< const char *, std::decay_t< t_Subtree > >, std::is_same< std::string_view, std::decay_t< t_Subtree > >, std::is_same< std::vector< std::string >, std::decay_t< t_Subtree > >> is_subtree
Definition: common.h:125
std::enable_if_t< not std::is_base_of_v< ariles2::visitor::Visitor, t_Visitor > > is_not_visitor_t
Definition: common.h:138
std::enable_if_t< not is_subtree< t_Subtree >::value > is_not_subtree_t
Definition: common.h:131
Definition: basic.h:17
t_Visitor::ReturnType apply(t_Visitor &visitor, t_Ariles &ariles_class, t_Subtree &&subtree, const typename t_Visitor::Parameters &param)
Definition: common.h:165
#define CPPUT_TRACE_FUNCTION
Definition: trace.h:126