OMNeT++ Simulation Library  5.6.1
simutil.h
1 //==========================================================================
2 // SIMUTIL.H - part of
3 // OMNeT++/OMNEST
4 // Discrete System Simulation in C++
5 //
6 //==========================================================================
7 
8 /*--------------------------------------------------------------*
9  Copyright (C) 1992-2017 Andras Varga
10  Copyright (C) 2006-2017 OpenSim Ltd.
11 
12  This file is distributed WITHOUT ANY WARRANTY. See the file
13  `license' for details on this and other legal matters.
14 *--------------------------------------------------------------*/
15 
16 #ifndef __OMNETPP_SIMUTIL_H
17 #define __OMNETPP_SIMUTIL_H
18 
19 #include <type_traits> // is_integer
20 #include <limits> // numeric_limits
21 #include <cstring> // for strlen, etc.
22 #include <cstdarg> // for va_list
23 #include <cstdio> // for sprintf
24 #include <cstdlib> // for gcvt
25 #include <typeinfo> // for type_info
26 #include <string> // for std::string
27 #include "platdep/platmisc.h" // for gcvt, etc
28 #include "simkerneldefs.h"
29 #include "errmsg.h"
30 
31 namespace omnetpp {
32 
33 // forward declarations
34 class cObject;
35 class cComponent;
36 
37 // logically belongs to csimulation.h but must be here because of declaration order
38 enum {CTX_NONE, CTX_BUILD, CTX_INITIALIZE, CTX_EVENT, CTX_REFRESHDISPLAY, CTX_FINISH, CTX_CLEANUP};
39 
40 
43 
44 // helpers for checked_int_cast
45 void intCastError(const std::string& num, const char *errmsg=nullptr);
46 void intCastError(const std::string& num, const cObject *context, const char *errmsg=nullptr);
47 
53 template<typename ToInt, typename FromInt>
54 ToInt checked_int_cast(FromInt x, const char *errmsg=nullptr)
55 {
56  static_assert(std::is_integral<ToInt>::value && std::is_integral<FromInt>::value, "checked_int_cast expects integers");
57  ToInt res = x;
58  if ((x<0) != (res<0) || x-res != 0) // note: x!=res would result in warning: signed-unsigned comparison
59  intCastError(std::to_string(x), errmsg);
60  return res;
61 }
62 
68 template<typename ToInt, typename FromInt>
69 ToInt checked_int_cast(FromInt x, const cObject *context, const char *errmsg=nullptr)
70 {
71  static_assert(std::is_integral<ToInt>::value && std::is_integral<FromInt>::value, "checked_int_cast expects integers");
72  ToInt res = x;
73  if ((x<0) != (res<0) || x-res != 0) // note: x!=res would result in warning: signed-unsigned comparison
74  intCastError(std::to_string(x), context, errmsg);
75  return res;
76 }
77 
83 template<typename ToInt>
84 ToInt checked_int_cast(double d, const char *errmsg=nullptr)
85 {
86  static_assert(std::is_integral<ToInt>::value, "checked_int_cast expects integer template argument");
87  if (d < std::numeric_limits<ToInt>::min() || d > std::numeric_limits<ToInt>::max())
88  intCastError(std::to_string(d), errmsg);
89  return (ToInt)d;
90 }
91 
96 inline int opp_strlen(const char *);
97 
102 inline char *opp_strdup(const char *);
103 
108 inline char *opp_strcpy(char *,const char *);
109 
114 inline int opp_strcmp(const char *, const char *);
115 
121 SIM_API char *opp_strprettytrunc(char *dest, const char *src, unsigned maxlen);
122 
126 SIM_API const char *opp_typename(const std::type_info& t);
127 
135 SIM_API int64_t opp_get_monotonic_clock_nsecs(); // in gettime.cc
136 
144 SIM_API int64_t opp_get_monotonic_clock_usecs(); // in gettime.cc
145 
147 
148 // INTERNAL: returns the name of a C++ type, correcting the quirks of various compilers.
149 SIM_API const char *opp_demangle_typename(const char *mangledName);
150 
151 
173 #define Enter_Method omnetpp::cMethodCallContextSwitcher __ctx(this); __ctx.methodCall
174 
194 #define Enter_Method_Silent omnetpp::cMethodCallContextSwitcher __ctx(this); __ctx.methodCallSilent
195 
203 class SIM_API cContextSwitcher
204 {
205  protected:
206  cComponent *callerContext;
207  public:
211  cContextSwitcher(const cComponent *newContext);
212 
216  ~cContextSwitcher();
217 };
218 
224 {
225  private:
226  static int depth;
227 
228  public:
232  //TODO store previous frame, __FILE__, __LINE__, __FUNCTION__ too, at least in debug builds?
233  cMethodCallContextSwitcher(const cComponent *newContext);
234 
239 
244  void methodCall(const char *methodFmt,...);
245  void methodCallSilent(const char *methodFm,...);
246  void methodCallSilent();
247 
251  static int getDepth() {return depth;}
252 };
253 
261 class SIM_API cContextTypeSwitcher
262 {
263  private:
264  int savedcontexttype;
265 
266  public:
270  cContextTypeSwitcher(int contexttype);
271 
276 };
277 
278 // implementations:
279 
280 inline char *opp_strcpy(char *s1,const char *s2)
281 {
282  return strcpy(s1, s2 ? s2 : "");
283 }
284 
285 inline int opp_strlen(const char *s)
286 {
287  return s ? strlen(s) : 0;
288 }
289 
290 inline char *opp_strdup(const char *s)
291 {
292  if (!s || !s[0]) return nullptr;
293  char *p = new char[strlen(s)+1];
294  strcpy(p,s);
295  return p;
296 }
297 
298 inline char *opp_strdup(const char *s, int len)
299 {
300  if (!s || !s[0]) return nullptr;
301  char *p = new char[len+1];
302  strncpy(p,s,len);
303  p[len] = 0;
304  return p;
305 }
306 
307 inline int opp_strcmp(const char *s1, const char *s2)
308 {
309  if (s1)
310  return s2 ? strcmp(s1,s2) : (*s1 ? 1 : 0);
311  else
312  return (s2 && *s2) ? -1 : 0;
313 }
314 
315 // internally used: appends [num] to the given string
316 inline void opp_appendindex(char *s, unsigned int i)
317 {
318  while (*s) s++;
319  *s++ = '[';
320  if (i<10)
321  {*s++ = '0'+i; *s++=']'; *s=0; return;}
322  if (i<100)
323  {*s++ = '0'+i/10; *s++='0'+i%10; *s++=']'; *s=0; return;}
324  sprintf(s,"%d]",i);
325 }
326 
327 // internal
328 inline std::string double_to_str(double t)
329 {
330 #if __cplusplus >= 201103L
331  return std::to_string(t);
332 #else
333  char buf[32];
334  return gcvt(t,16,buf);
335 #endif
336 }
337 
338 } // namespace omnetpp
339 
340 #endif
341 
342 
SIM_API int64_t opp_get_monotonic_clock_nsecs()
Returns a monotonic time in nanoseconds since some unspecified starting point. This clock is not affe...
Common base for module and channel classes.
Definition: ccomponent.h:48
Root of the OMNeT++ class hierarchy. cObject is a lightweight class without any data members...
Definition: cobject.h:58
SIM_API char * opp_strprettytrunc(char *dest, const char *src, unsigned maxlen)
Copies src string into dest, and if its length would exceed maxlen, it is truncated with an ellipsis...
char * opp_strdup(const char *)
Duplicates the string, using new char[]. For nullptr and empty strings it returns nullptr...
Definition: simutil.h:290
Internal class. May only be used via the Enter_Method() and Enter_Method_Silent() macros! ...
Definition: simutil.h:223
char * opp_strcpy(char *, const char *)
Same as the standard strcpy() function, except that nullptr as the second argument is treated as an e...
Definition: simutil.h:280
The constructor switches the context to the given component, and the destructor restores the original...
Definition: simutil.h:203
Definition: cabstracthistogram.h:21
The constructor switches the context type, and the destructor restores the original context type...
Definition: simutil.h:261
ToInt checked_int_cast(double d, const char *errmsg=nullptr)
Safe integer cast: it throws an exception if in case of an overflow, i.e. when if the target type can...
Definition: simutil.h:84
int opp_strcmp(const char *, const char *)
Same as the standard strcmp() function, except that nullptr is treated exactly as an empty string (""...
Definition: simutil.h:307
SIM_API int64_t opp_get_monotonic_clock_usecs()
Returns a monotonic time in microseconds since some unspecified starting point. This clock is not aff...
int opp_strlen(const char *)
Same as the standard strlen() function, except that it also accepts nullptr and returns 0 for it...
Definition: simutil.h:285
SIM_API const char * opp_typename(const std::type_info &t)
Returns the name of a C++ type, correcting the quirks of various compilers.
static int getDepth()
Definition: simutil.h:251