Remote Call Framework 3.1
VariableArgMacro.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2019, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 3.1
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_UTIL_VARIABLEARGMACRO_HPP
20 #define INCLUDE_UTIL_VARIABLEARGMACRO_HPP
21 
22 #include <typeinfo>
23 #include <cstdint>
24 
25 #include <RCF/MemStream.hpp>
26 #include <RCF/Export.hpp>
27 //#include <RCF/ThreadLibrary.hpp>
28 
29 namespace RCF {
30 
31  class MemOstream;
32 
33  // These use sprintf to speed things up.
34  RCF_EXPORT void printToOstream(MemOstream & os, std::uint16_t n);
35  RCF_EXPORT void printToOstream(MemOstream & os, std::uint32_t n);
36  RCF_EXPORT void printToOstream(MemOstream & os, std::uint64_t n);
37 
38  // Operator<< , simple but slow. Sometimes causes memory allocations.
39  template<typename T>
40  void printToOstream(MemOstream & os, const T & t)
41  {
42  os << t;
43  }
44 
45 } // namespace RCF
46 
47 namespace RCF {
48 
49  class RCF_EXPORT VariableArgMacroFunctor
50  {
51  public:
52 
53  VariableArgMacroFunctor();
54  virtual ~VariableArgMacroFunctor();
55 
56  VariableArgMacroFunctor &init(
57  const std::string &label,
58  const std::string &msg,
59  const char *file,
60  int line,
61  const char *func);
62 
63  template<typename T>
64  void notify(const T &t, const char *name)
65  {
66  *mArgs << name << "=";
67  printToOstream(*mArgs, t);
68  *mArgs << ", ";
69  }
70 
71  void notify(std::size_t t, const char *name)
72  {
73  *mArgs << name << "=";
74  printToOstream(*mArgs, t);
75  *mArgs << ", ";
76  }
77 
78  // TODO: fix this properly
79 #ifdef _UNICODE
80  void notify(const wchar_t *, const char *) {}
81  void notify(const std::wstring &, const char *) {}
82 #endif
83 
84  template<typename T> T &cast()
85  {
86  return dynamic_cast<T &>(*this);
87  }
88 
89  template<typename T> T &cast(T *)
90  {
91  return dynamic_cast<T &>(*this);
92  }
93 
94  MemOstream * mHeader;
95  MemOstream * mArgs;
96 
97  const char * mFile;
98  int mLine;
99  const char * mFunc;
100  };
101 
102  class DummyVariableArgMacroObject
103  {
104  public:
105  template<typename T>
106  DummyVariableArgMacroObject &operator()(const T &)
107  {
108  return *this;
109  }
110  };
111 
112  #define DUMMY_VARIABLE_ARG_MACRO() \
113  if (false) ::RCF::DummyVariableArgMacroObject()
114 
115 } // namespace RCF
116 
117 
118 #define DECLARE_VARIABLE_ARG_MACRO(macro_name, functor) \
119  DECLARE_VARIABLE_ARG_MACRO_(macro_name, macro_name##_A, macro_name##_B, functor)
120 
121 #define DECLARE_VARIABLE_ARG_MACRO_( macro_name, macro_name_A, macro_name_B, functor) \
122  template<typename Functor> \
123  class VariableArgMacro; \
124  \
125  template<> class \
126  VariableArgMacro< functor > : public functor \
127  { \
128  public: \
129  VariableArgMacro() : \
130  macro_name_A(*this), macro_name_B(*this) \
131  {} \
132  template<typename T1> \
133  VariableArgMacro(const T1 &t1) : \
134  functor(t1), macro_name_A(*this), macro_name_B(*this) \
135  {} \
136  template<typename T1, typename T2> \
137  VariableArgMacro(const T1 &t1, const T2 &t2) : \
138  functor(t1,t2), macro_name_A(*this), macro_name_B(*this) \
139  {} \
140  template<typename T1, typename T2> \
141  VariableArgMacro(const T1 &t1, T2 &t2) : \
142  functor(t1,t2), macro_name_A(*this), macro_name_B(*this) \
143  {} \
144  template<typename T1, typename T2, typename T3> \
145  VariableArgMacro(const T1 &t1, const T2 &t2, const T3 & t3) : \
146  functor(t1,t2,t3), macro_name_A(*this), macro_name_B(*this) \
147  {} \
148  template<typename T1, typename T2, typename T3, typename T4, typename T5> \
149  VariableArgMacro(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : \
150  functor(t1,t2,t3,t4,t5), macro_name_A(*this), macro_name_B(*this) \
151  {} \
152  ~VariableArgMacro() \
153  {} \
154  VariableArgMacro &macro_name_A; \
155  VariableArgMacro &macro_name_B; \
156  template<typename T> \
157  VariableArgMacro< functor > &notify_(const T &t, const char *name) \
158  { \
159  notify(t,name); return *this; \
160  } \
161  VariableArgMacro< functor > &notify_(size_t t, const char *name) \
162  { \
163  notify(t,name); return *this; \
164  } \
165  }
166 
167 #define DECLARE_VARIABLE_ARG_MACRO_T1( macro_name, functor ) \
168  DECLARE_VARIABLE_ARG_MACRO_T1_(macro_name, macro_name##_A, macro_name##_B, functor)
169 
170 #define DECLARE_VARIABLE_ARG_MACRO_T1_( macro_name, macro_name_A, macro_name_B, functor) \
171  template<typename Functor> \
172  class VariableArgMacro; \
173  \
174  template<typename U> \
175  class VariableArgMacro< functor<U> > : public functor<U> \
176  { \
177  public: \
178  VariableArgMacro() : \
179  macro_name_A(*this), macro_name_B(*this) \
180  {} \
181  template<typename T1> \
182  VariableArgMacro(const T1 &t1) : \
183  functor<U>(t1), macro_name_A(*this), macro_name_B(*this) \
184  {} \
185  template<typename T1, typename T2> \
186  VariableArgMacro(const T1 &t1, const T2 &t2) : \
187  functor<U>(t1,t2), macro_name_A(*this), macro_name_B(*this) \
188  {} \
189  ~VariableArgMacro() \
190  {} \
191  VariableArgMacro &macro_name_A; \
192  VariableArgMacro &macro_name_B; \
193  template<typename T> \
194  VariableArgMacro< functor<U> > &notify_(const T &t, const char *name) \
195  { \
196  notify(t,name); \
197  return *this; \
198  } \
199  VariableArgMacro< functor<U> > &notify_(size_t t, const char *name) \
200  { \
201  notify(t,name); \
202  return *this; \
203  } \
204  }
205 
206 #define DECLARE_VARIABLE_ARG_MACRO_T2( macro_name, functor ) \
207  DECLARE_VARIABLE_ARG_MACRO_T2_(macro_name, macro_name##_A, macro_name##_B, functor)
208 
209 #define DECLARE_VARIABLE_ARG_MACRO_T2_( macro_name, macro_name_A, macro_name_B, functor) \
210  template<typename Functor> \
211  class VariableArgMacro; \
212  \
213  template<typename U, typename V> \
214  class VariableArgMacro< functor<U,V> > : public functor<U,V> \
215  { \
216  public: \
217  VariableArgMacro() : \
218  macro_name_A(*this), macro_name_B(*this) \
219  {} \
220  template<typename T1> \
221  VariableArgMacro(const T1 &t1) : \
222  functor<U,V>(t1), macro_name_A(*this), macro_name_B(*this) \
223  {} \
224  template<typename T1, typename T2> \
225  VariableArgMacro(const T1 &t1, const T2 &t2) : \
226  functor<U,V>(t1,t2), macro_name_A(*this), macro_name_B(*this) \
227  {} \
228  ~VariableArgMacro() \
229  {} \
230  VariableArgMacro &macro_name_A; \
231  VariableArgMacro &macro_name_B; \
232  template<typename T> \
233  VariableArgMacro< functor<U,V> > &notify_(const T &t, const char *name) \
234  { \
235  notify(t,name); \
236  return *this; \
237  } \
238  VariableArgMacro< functor<U,V> > &notify_(size_t t, const char *name) \
239  { \
240  notify(t,name); \
241  return *this; \
242  } \
243  }
244 
245 #endif // ! INCLUDE_UTIL_VARIABLEARGMACRO_HPP
Definition: AmiIoHandler.hpp:24
RCF_EXPORT bool init(RcfConfigT *=nullptr)
Reference-counted initialization of RCF library. May be called multiple times (see deinit())...