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