Program listing for file kernel/src/utils/SiconosTools/SiconosVisitor.hpp#

  1#ifndef SiconosVisitor_hpp
  2#define SiconosVisitor_hpp
  3
  4
  5
  6#include "SiconosException.hpp"
  7#include "SiconosPointers.hpp"
  8
  9#include "SiconosVisitables.hpp"
 10
 11
 12#define SICONOS_VISITOR_QUOTE(M) #M
 13
 14#define SICONOS_VISITOR_FAIL(X)                                         \
 15  { THROW_EXCEPTION                                         \
 16      ( SICONOS_VISITOR_QUOTE(you must define a visit function for X in a derived class of SiconosVisitor)); }
 17
 18
 19
 20#define VIRTUAL_ACCEPT_VISITORS(FROMCLASS)                              \
 21  template<typename Archive> friend class SiconosSerializer;            \
 22  virtual void acceptSP(SP::SiconosVisitor)                             \
 23  {                                                                     \
 24    THROW_EXCEPTION                                         \
 25      ( SICONOS_VISITOR_QUOTE(this class derived from FROMCLASS does not accept a visitor for shared pointers)); \
 26  };                                                                    \
 27  virtual void accept(SiconosVisitor&) const                            \
 28  {                                                                     \
 29    THROW_EXCEPTION                                         \
 30      ( "accept: no visitor defined");                                  \
 31  };                                                                    \
 32  virtual void acceptSerializer(SiconosVisitor&)                        \
 33  {                                                                     \
 34    THROW_EXCEPTION                                         \
 35      ( "acceptSerializer: no serializer defined");                     \
 36  };                                                                    \
 37  virtual inline Type::Siconos acceptType(FindType& ft) const           \
 38  { THROW_EXCEPTION                                         \
 39      ( SICONOS_VISITOR_QUOTE(this class derived from FROMCLASS does not accept a type visitor)); \
 40    return Type::void_type;                                             \
 41  }                                                                     \
 42
 43
 44#define ACCEPT_STD_VISITORS()                                           \
 45  template<typename Archive> friend class SiconosSerializer;            \
 46  void accept(SiconosVisitor& tourist) const override { tourist.visit(*this); } \
 47  void acceptSerializer(SiconosVisitor& serializer) override{ serializer.visit(*this); } \
 48  inline Type::Siconos acceptType(FindType& ft) const override { return ft.visit(*this); } \
 49
 50#define ACCEPT_NONVIRTUAL_VISITORS()                                    \
 51  template<typename Archive> friend class SiconosSerializer;            \
 52  void accept(SiconosVisitor& tourist) const { tourist.visit(*this); }  \
 53  void acceptSerializer(SiconosVisitor& serializer) { serializer.visit(*this); } \
 54  inline Type::Siconos acceptType(FindType& ft) const { return ft.visit(*this); } \
 55
 56#define ACCEPT_SP_VISITORS()                                            \
 57  void acceptSP(SP::SiconosVisitor tourist) override{ tourist->visit(shared_from_this()); }
 58
 59#define ACCEPT_VISITORS()                       \
 60  ACCEPT_SP_VISITORS()                          \
 61  ACCEPT_STD_VISITORS()                         \
 62
 63
 64#define ACCEPT_BASE_STD_VISITORS(BASE)                                  \
 65  template<typename Archive> friend class SiconosSerializer;            \
 66  virtual void acceptBase(SiconosVisitor& tourist) const { tourist.visit(*static_cast<const BASE *>(this)); } \
 67  virtual void accept(SiconosVisitor& tourist) const { tourist.visit(*this); } \
 68  virtual void acceptSerializerBase(SiconosVisitor& serializer) { serializer.visit(*static_cast<const BASE *>(this)); } \
 69  virtual void acceptSerializer(SiconosVisitor& serializer) { serializer.visit(*this); } \
 70  virtual inline Type::Siconos acceptType(FindType& ft) const { return ft.visit(*static_cast<const BASE *>(this)); } \
 71
 72#define ACCEPT_BASE_NONVIRTUAL_VISITORS(BASE)                           \
 73  template<typename Archive> friend class SiconosSerializer;            \
 74  void acceptBase(SiconosVisitor& tourist) const { tourist.visit(*static_cast<const BASE *>(this)); } \
 75  void accept(SiconosVisitor& tourist) const { tourist.visit(*this); } \
 76  void acceptSerializerBase(SiconosVisitor& serializer) { serializer.visit(*static_cast<const BASE *>(this)); } \
 77  void acceptSerializer(SiconosVisitor& serializer) { serializer.visit(*this); } \
 78  inline Type::Siconos acceptType(FindType& ft) const { return ft.visit(*static_cast<const BASE *>(this)); } \
 79
 80#define ACCEPT_BASE_SP_VISITORS(BASE)                                   \
 81  virtual void acceptSPBase(SP::SiconosVisitor tourist) { tourist->visit(std::static_pointer_cast<BASE>(shared_from_this())); }\
 82  virtual void acceptSP(SP::SiconosVisitor tourist) { tourist->visit(shared_from_this()); }
 83
 84#define ACCEPT_BASE_VISITORS(BASE)                           \
 85  ACCEPT_BASE_SP_VISITORS(BASE)                              \
 86  ACCEPT_BASE_STD_VISITORS(BASE)                             \
 87
 88
 89#undef REGISTER
 90#undef REGISTER_STRUCT
 91
 92#define REGISTER(X) class X;
 93#define REGISTER_STRUCT(X) struct X;
 94
 95#undef REGISTER_BASE
 96#undef REGISTER_BASE_EXTERN
 97#define REGISTER_BASE(X,Y) REGISTER(X)
 98#define REGISTER_BASE_EXTERN(X,Y) REGISTER(X)
 99
100SICONOS_VISITABLES()
101
102
103#undef REGISTER
104#undef REGISTER_STRUCT
105#define REGISTER(X) X,
106
107#define REGISTER_STRUCT(X) X,
108
109#undef REGISTER_BASE
110#undef REGISTER_BASE_EXTERN
111#define REGISTER_BASE(X,Y) REGISTER(X)
112#define REGISTER_BASE_EXTERN(X,Y) REGISTER(X)
113namespace Type
114{
115enum Siconos
116{
117  SICONOS_VISITABLES()
118  void_type
119};
120}
121
122
123
124
125
126
127#undef REGISTER
128#define REGISTER(X)                                                 \
129  Type::Siconos visit(const X&) const { return Type::X; };  \
130
131#undef REGISTER_STRUCT
132#define REGISTER_STRUCT(X) REGISTER(X)
133
134#undef REGISTER_BASE
135#undef REGISTER_BASE_EXTERN
136#define REGISTER_BASE(X,Y)                                         \
137  Type::Siconos visit(const X&) const { return Type::Y; }; \
138
139#define REGISTER_BASE_EXTERN(X,Y) REGISTER_BASE(X,Y)
140
141struct FindType
142{
143  SICONOS_VISITABLES()
144};
145
146
147#undef REGISTER
148#define REGISTER(X)             \
149  virtual void visit(std::shared_ptr<X>) SICONOS_VISITOR_FAIL(SP :: X); \
150  virtual void visit(X&) SICONOS_VISITOR_FAIL(X);                         \
151  virtual void visit(const X&) SICONOS_VISITOR_FAIL(X);
152
153#undef REGISTER_STRUCT
154#define REGISTER_STRUCT(X) REGISTER(X)
155
156#undef REGISTER_BASE
157#undef REGISTER_BASE_EXTERN
158#define REGISTER_BASE(X,Y) REGISTER(X)
159
160#define REGISTER_BASE_EXTERN(X,Y) REGISTER_BASE(X,Y)
161
162struct SiconosVisitor
163{
164  SICONOS_VISITABLES()
165  virtual ~SiconosVisitor() noexcept = default;
166};
167
168
169namespace Type
170{
171static FindType find;
172
173template <typename C>
174inline Siconos value(const C& c)
175{
176  return c.acceptType(find);
177}
178}
179
180
181TYPEDEF_SPTR(SiconosVisitor)
182
183#undef REGISTER
184#undef REGISTER_STRUCT
185#undef REGISTER_BASE
186#undef REGISTER_BASE_EXTERN
187
188
189#endif