RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
VariableArgMacro.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, 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: 2.0
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
24 #include <boost/cstdint.hpp>
25 #include <boost/noncopyable.hpp>
26
27 #include <RCF/MemStream.hpp>
28 #include <RCF/Export.hpp>
29 #include <RCF/ThreadLibrary.hpp>
30
31 namespace RCF {
32
33 // These use sprintf to speed things up.
34 RCF_EXPORT void printToOstream(std::ostream & os, boost::uint16_t n);
35 RCF_EXPORT void printToOstream(std::ostream & os, boost::uint32_t n);
36 RCF_EXPORT void printToOstream(std::ostream & os, boost::uint64_t n);
37
38 // Operator<< , simple but slow. Sometimes causes memory allocations.
39 template<typename T>
40 void printToOstream(std::ostream & os, const T & t)
41 {
42 os << t;
43 }
44
45 } // namespace RCF
46
47 namespace util {
48
49 class RCF_EXPORT VariableArgMacroFunctor : boost::noncopyable
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 RCF::printToOstream(*mArgs, t);
68 *mArgs << ", ";
69 }
70
71 void notify(std::size_t t, const char *name)
72 {
73 *mArgs << name << "=";
74 RCF::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 RCF::MemOstream * mHeader;
95 RCF::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) ::util::DummyVariableArgMacroObject()
114
115 } // namespace util
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