GranOO  3.0
A robust and versatile workbench to build 3D dynamic simulations based on the Discrete Element Method
Macro.hpp
Go to the documentation of this file.
1 // This file is part of GranOO, a workbench for DEM simulation.
2 //
3 // Author(s) : - Damien Andre IRCER/UNILIM, Limoges France
4 // <damien.andre@unilim.fr>
5 // - Jean-luc Charles Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
6 // <jean-luc.charles@ensam.eu>
7 // - Jeremie Girardot Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
8 // <jeremie.girardot@ensam.eu>
9 // - Cedric Hubert LAMIH/UPHF, Valenciennes France
10 // <cedric.hubert@uphf.fr>
11 // - Ivan Iordanoff Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
12 // <ivan.iordanoff@ensam.eu>
13 //
14 // Copyright (C) 2008-2019 D. Andre, JL. Charles, J. Girardot, C. Hubert, I. Iordanoff
15 //
16 // This program is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 // This program is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 
29 #ifndef _GranOO_LibUtil_AssertMsg_H
30 #define _GranOO_LibUtil_AssertMsg_H
31 
32 #include <string>
33 #include <vector>
34 
35 // This macro can replace the standard 'assert' macro.
36 // The UserAssert macro can be used to detect user error.
37 
38 #ifdef SAFE_MODE
39 # define SafeModeAssert(condition, message) \
40  do { \
41  if (!(condition)) { \
42  std::vector<std::string> backtrace = GranOO3::Core::AssertMsg::Backtrace(); \
43  GranOO3::Core::AssertMsg::RaiseUserAssertion(__LINE__, __FILE__, #condition, message, backtrace); \
44  } \
45  } while (false)
46 #else
47 # define SafeModeAssert(condition, message)
48 #endif
49 
50 
51 
52 
53 #ifndef NDEBUG
54 # define UserAssert(condition, message) \
55  do { \
56  if (!(condition)) { \
57  std::vector<std::string> backtrace = GranOO3::Core::AssertMsg::Backtrace(); \
58  GranOO3::Core::AssertMsg::RaiseUserAssertion(__LINE__, __FILE__, #condition, message, backtrace); \
59  } \
60  } while (false)
61 #else
62 # define UserAssert(condition, message) do { } while (false)
63 #endif
64 
65 // Same as UserAssert
66 #ifndef NDEBUG
67 # define AssertMsg(condition, message) \
68  do { \
69  if (!(condition)) { \
70  std::vector<std::string> backtrace = GranOO3::Core::AssertMsg::Backtrace(); \
71  GranOO3::Core::AssertMsg::RaiseUserAssertion(__LINE__, __FILE__, #condition, message, backtrace); \
72  } \
73  } while (false)
74 #else
75 # define AssertMsg(condition, message) do { } while (false)
76 #endif
77 
78 
79 // The InternAssert macro can be used to detect intern error.
80 #ifndef NDEBUG
81 # define InternAssert(condition) \
82  do { \
83  if (!(condition)) { \
84  std::vector<std::string> backtrace = GranOO3::Core::AssertMsg::Backtrace(); \
85  GranOO3::Core::AssertMsg::RaiseInternAssertion(__LINE__, __FILE__, #condition, backtrace); \
86  } \
87  } while (false)
88 #else
89 # define InternAssert(condition) do { } while (false)
90 #endif
91 
92 #ifndef NDEBUG
93 # define InternAssertMsg(condition, message) \
94  do { \
95  if (!(condition)) { \
96  std::vector<std::string> backtrace = GranOO3::Core::AssertMsg::Backtrace(); \
97  GranOO3::Core::AssertMsg::RaiseInternAssertionMsg(__LINE__, __FILE__, #condition, message, backtrace); \
98  } \
99  } while (false)
100 #else
101 # define InternAssertMsg(condition, message) do { } while (false)
102 #endif
103 
104 
105 
106 namespace GranOO3
107 {
108  namespace Core
109  {
110 
111  class AssertMsg
112  {
113  public:
114  static void RaiseUserAssertion(int line, const std::string& file,
115  const std::string& condition, const std::string& message, const std::vector<std::string> &backtrace);
116  static void RaiseInternAssertion(int line, const std::string& file,
117  const std::string& condition, const std::vector<std::string> &backtrace);
118  static void RaiseInternAssertionMsg(int line, const std::string& file,
119  const std::string& condition, const std::string& message, const std::vector<std::string> &backtrace);
120 
121  static std::vector<std::string> Backtrace(int skip = 1);
122  };
123 
124  }
125 }
126 
127 #define TODO \
128  InternAssertMsg(0, "This function is not yet implemented !");
129 
130 
131 // Macro to insert hard-coded ascii file
132 #define GRANOO_DECLARE_EXTERN_FILE(FILE) \
133  extern "C" const char FILE[]; \
134  extern "C" const size_t FILE ## _len;
135 
136 #define GRANOO_FILE_TO_STRING(FILE) \
137  std::string(FILE, FILE ## _len)
138 
139 // This is a macro to automatic access to class member, for example the macro
140 // GRANOO_ACCESSOR(Mass, double, mass_); -> will give the 4 members fonctions
141 // - double& mass() {return mass_};
142 // - const double& mass() const {return mass_};
143 // - const double& get_mass() const {return mass_};
144 // - void set_Mass(const double& val){mass_ = val};
145 //
146 // Note that these functions are inlined !
147 
148 
149 #define GRANOO_ACCESS_REF(method, type, variable) \
150  \
151  type & method () {return variable;} \
152  \
153  type & RW_ ## method () {return variable;} // Unique name to avoid overloading
154 
155 #define GRANOO_ACCESS_REF_PTR(method, type, variable) \
156  \
157  type & method () {return *variable;} \
158  \
159  type & RW_ ## method () {return *variable;} // Unique name to avoid overloading
160 
161 #define GRANOO_ACCESS_REF_CONST(method, type, variable) \
162  \
163  const type & method () const {return variable;} \
164  \
165  const type & RO_ ## method () const {return variable;} // Unique name to avoid overloading
166 
167 #define GRANOO_ACCESS_REF_CONST_PTR(method, type, variable) \
168  \
169  const type & method () const {return *variable;} \
170  \
171  const type & RO_ ## method () const {return *variable;} // Unique name to avoid overloading
172 
173 #define GRANOO_ACCESS_GET(method, type, variable) \
174  \
175  const type & get_ ## method () const {return variable;}
176 
177 #define GRANOO_ACCESS_GET_PTR(method, type, variable) \
178  \
179  const type & get_ ## method () const {return *variable;}
180 
181 #define GRANOO_ACCESS_GET_COPY(method, type, variable) \
182  \
183  type get_ ## method () const {return variable;}
184 
185 #define GRANOO_ACCESS_SET(method, type, variable) \
186  \
187  void set_ ## method (const type& val) {variable = val;}
188 
189 #define GRANOO_ACCESS_SET_COPY(method, type, variable) \
190  \
191  void set_ ## method (type val) {variable = val;}
192 
193 #define GRANOO_ACCESS_SET_POS(method, type, variable) \
194  \
195  void set_ ## method (const type& val) { \
196  AssertMsg(val >= 0., "The value must be positive"); \
197  variable = val;}
198 
199 #define GRANOO_ACCESS(method, type, variable) \
200  GRANOO_ACCESS_REF (method, type, variable) \
201  GRANOO_ACCESS_REF_CONST(method, type, variable) \
202  GRANOO_ACCESS_GET (method, type, variable) \
203  GRANOO_ACCESS_SET (method, type, variable)
204 
205 #define GRANOO_ACCESS_POS(method, type, variable) \
206  GRANOO_ACCESS_GET (method, type, variable) \
207  GRANOO_ACCESS_SET_POS (method, type, variable)
208 
209 
210 // Export field macro
211 #define GRANOO_EXPORT_FIELD(CLASS, VTK_DATA_TYPE, ...) \
212  const bool CLASS::register_field_ = RegisterField(); \
213  bool CLASS::RegisterField() { \
214  get_FieldCollector().set_VtkData(VTK_DATA_TYPE); \
215  get_FieldCollector().add(__VA_ARGS__); return true;}
216 
217 #define GRANOO_EXPORT_FIELD_T(CLASS, VTK_DATA_TYPE, ...) \
218  template<typename T> \
219  const bool CLASS<T>::register_field_ = RegisterField(); \
220  template<typename T> bool CLASS<T>::RegisterField() { \
221  get_FieldCollector().set_VtkData(VTK_DATA_TYPE); \
222  get_FieldCollector().add(__VA_ARGS__); return true;}
223 
224 
225 # define GRANOO_CLASS_BASE(CLASS, BASE) \
226 public: \
227  static const bool register_granoo_class_; \
228  static const unsigned int class_rank_ID; \
229  static const std::string class_ID() {return #CLASS;} \
230  static Core::SetOf<CLASS>& all(const std::string& id) \
231  {return Core::SetOf<CLASS>::get(id);} \
232  static CLASS& all(unsigned int index) \
233  {return Core::SetOf<CLASS>::get()(index);} \
234  static Core::SetOf<CLASS>& all() \
235  {return Core::SetOf<CLASS>::get();} \
236  using Set = Core::SetOf<CLASS>; \
237  static const size_t class_num_ID() {return std::hash<std::string>()(#CLASS);} \
238  virtual const std::string top_class_ID() const {return class_ID();} \
239  virtual const unsigned int top_class_rank_ID() const {return class_rank_ID;} \
240  virtual const size_t global_rank() const \
241  {return this->Core::Register<CLASS>::get_numeric_ID();} \
242  static Core::FieldCollector<CLASS>& get_FieldCollector() \
243  {return Core::FieldCollector<CLASS>::get();}; \
244  static bool RegisterField(); \
245  static const bool register_field_; \
246  typedef BASE base; \
247  virtual void add(Core::SetOfGeneric* set) \
248  {Core::SetOf<CLASS>::get_safe(set).add_item_in_class_hierarchy(this, set);} \
249  virtual void erase(Core::SetOfGeneric* set) \
250  {Core::SetOf<CLASS>::get_safe(set).erase_item_in_class_hierarchy(this, set);} \
251  bool in(const Core::SetOf<CLASS>&set) const \
252  {return this->Core::Register<CLASS>::belong_to_setof(set);} \
253  bool in(const std::string& id) const \
254  {return this->Core::Register<CLASS>::belong_to_setof(id);}
255 
256 
257 // Macros that declare and register a GranOO class
258 # define GRANOO_CLASS(CLASS, BASE) \
259  GRANOO_CLASS_BASE(CLASS, BASE) \
260  template<class T>T& prop() \
261  {return Core::PropWrapper<std::is_base_of< Core::PropClass< CLASS >, \
262  CLASS>::value>::prop<T, CLASS>(*this);} \
263  template<class T> const T& get_prop() const \
264  {return Core::PropWrapper<std::is_base_of< Core::PropClass< CLASS >, \
265  CLASS>::value>::get_prop<T, CLASS>(*this);} \
266  template<class T>T& new_prop() \
267  {return Core::PropWrapper<std::is_base_of< Core::PropClass< CLASS >, \
268  CLASS>::value>::new_prop<T, CLASS>(*this);} \
269  virtual bool is(size_t i) const \
270  {if (i==class_num_ID()) return true; return base::is(i);} \
271  \
272  virtual void add_in(const std::string& set_ID) \
273  {Core::SetOf<CLASS>::pull(set_ID).add_item(this);}
274 
275 
276 
277 # define GRANOO_CLASS_T(CLASS, TPL, BASE) \
278  GRANOO_CLASS_BASE_T(CLASS, TPL, BASE) \
279  template<class T>T& prop() \
280  {return Core::PropWrapper<std::is_base_of< Core::PropClass< CLASS<TPL> >, \
281  CLASS<TPL> >::value>::template prop<T, CLASS<TPL> >(*this);} \
282  template<class T>const T& get_prop() const \
283  {return Core::PropWrapper<std::is_base_of< Core::PropClass< CLASS<TPL> >, \
284  CLASS<TPL> >::value>::template get_prop<T, CLASS<TPL> >(*this);} \
285  template<class T>T& new_prop() \
286  {return Core::PropWrapper<std::is_base_of< Core::PropClass< CLASS<TPL> >, \
287  CLASS<TPL> >::value>::template new_prop<T, CLASS<TPL> >(*this);} \
288  virtual bool is(size_t i) const \
289  {if (i==class_num_ID()) return true; return base::is(i);}
290 
291 
292 # define GRANOO_CLASS_BASE_T(CLASS, T, BASE) \
293 public: \
294  static const bool register_granoo_class_; \
295  static const unsigned int class_rank_ID; \
296  static const std::string class_ID() {return std::string(#CLASS)+"<"+T::class_ID()+">";}\
297  static Core::SetOf<CLASS<T> >& all(const std::string& id) \
298  {return Core::SetOf<CLASS<T> >::get(id);} \
299  static Core::SetOf<CLASS<T> >& all() \
300  {return Core::SetOf<CLASS<T> >::get();} \
301  using Set = Core::SetOf<CLASS<T> >; \
302  static const size_t class_num_ID() {return std::hash<std::string>()(#CLASS "<"#T ">");} \
303  virtual const std::string top_class_ID() const {return class_ID();} \
304  virtual const unsigned int top_class_rank_ID() const {return class_rank_ID;} \
305  virtual const size_t global_rank() const \
306  {return this->Core::Register<CLASS<T> >::get_numeric_ID();} \
307  static Core::FieldCollector<CLASS<T> >& get_FieldCollector() \
308  {return Core::FieldCollector<CLASS<T> >::get();}; \
309  static bool RegisterField(); \
310  static const bool register_field_; \
311  typedef BASE base; \
312  virtual void add(Core::SetOfGeneric* set) \
313  {Core::SetOf<CLASS<T> >::get_safe(set).add_item_in_class_hierarchy(this, set);} \
314  virtual void erase(Core::SetOfGeneric* set) \
315  {Core::SetOf<CLASS<T> >::get_safe(set).erase_item_in_class_hierarchy(this, set);} \
316  bool in(const Core::SetOf<CLASS<T> >&set) const \
317  {return this->Core::Register<CLASS<T> >::belong_to_setof(set);} \
318  bool in(const std::string& id) const \
319  {return this->Core::Register<CLASS<T> >::belong_to_setof(id);} \
320  virtual void add_in(const std::string& set_ID) \
321  {Core::SetOf<CLASS<T>>::pull(set_ID).add_item(this);}
322 
323 # define GRANOO_CLASS_REGISTER(CLASS) \
324  const bool CLASS::register_granoo_class_ = \
325  GranOO3::Core::SetOfManager::get().RegisterGranOOClass<CLASS>(); \
326  const unsigned int CLASS::class_rank_ID = \
327  GranOO3::Core::Base::affect_class_rank_ID();
328 
329 # define GRANOO_CLASS_REGISTER_T(CLASS, T) \
330  template<> const bool CLASS<T>::register_granoo_class_ = \
331  GranOO3::Core::SetOfManager::get().RegisterGranOOClass<CLASS<T> >();\
332  template<> const unsigned int CLASS<T>::class_rank_ID = \
333  GranOO3::Core::Base::affect_class_rank_ID();
334 
335 
336 # define GRANOO_CLASS_INSTANCIATE_TPL(CLASS) \
337  template class Core::Register< CLASS >; \
338  template class Core::SetOf< CLASS >; \
339  template class Core::SetOfMap< CLASS >; \
340  template class Core::NeedSetOf< CLASS >; \
341  template class Core::Signal< CLASS& >;
342 
343 # define GRANOO_CLASS_DECLARE_TPL(CLASS) \
344  extern template class Core::Register< CLASS >; \
345  extern template class Core::SetOf< CLASS >; \
346  extern template class Core::SetOfMap< CLASS >; \
347  extern template class Core::NeedSetOf< CLASS >; \
348  extern template class Core::Signal< CLASS& >;
349 
350 
351 
352 
353 # define GRANOO_CLASS_DEFAULT_COLOR(R,G,B,A) \
354 public: \
355  const Core::Color& default_color() const { \
356  static const Core::Color* c = new Core::Color(R,G,B,A); return *c;}
357 
358 
359 #endif
Definition: Macro.hpp:112
static void RaiseInternAssertionMsg(int line, const std::string &file, const std::string &condition, const std::string &message, const std::vector< std::string > &backtrace)
Definition: Macro.cpp:102
static void RaiseUserAssertion(int line, const std::string &file, const std::string &condition, const std::string &message, const std::vector< std::string > &backtrace)
Definition: Macro.cpp:50
static void RaiseInternAssertion(int line, const std::string &file, const std::string &condition, const std::vector< std::string > &backtrace)
Definition: Macro.cpp:78
static std::vector< std::string > Backtrace(int skip=1)
Definition: Macro.cpp:129
Definition: Common.hpp:198