GeNN  4.0.0
GPU enhanced Neuronal Networks (GeNN)
Util.h
Go to the documentation of this file.
1 #pragma once
2 #include <cassert>
3 #include <cstring>
4 #include <cstdio>
5 #include <sstream>
6 #include <fcntl.h>
7 #include <sys/stat.h>
8 
9 #ifndef PLOG_ENABLE_WCHAR_INPUT
10 # ifdef _WIN32
11 # define PLOG_ENABLE_WCHAR_INPUT 1
12 # else
13 # define PLOG_ENABLE_WCHAR_INPUT 0
14 # endif
15 #endif
16 
17 #ifdef _WIN32
18 # include <plog/WinApi.h>
19 # include <time.h>
20 # include <sys/timeb.h>
21 # include <io.h>
22 # include <share.h>
23 #elif defined(__rtems__)
24 # include <unistd.h>
25 # include <rtems.h>
26 # if PLOG_ENABLE_WCHAR_INPUT
27 # include <iconv.h>
28 # endif
29 #else
30 # include <unistd.h>
31 # include <sys/syscall.h>
32 # include <sys/time.h>
33 # include <pthread.h>
34 # if PLOG_ENABLE_WCHAR_INPUT
35 # include <iconv.h>
36 # endif
37 #endif
38 
39 #ifdef _WIN32
40 # define _PLOG_NSTR(x) L##x
41 # define PLOG_NSTR(x) _PLOG_NSTR(x)
42 #else
43 # define PLOG_NSTR(x) x
44 #endif
45 
46 namespace plog
47 {
48  namespace util
49  {
50 #ifdef _WIN32
51  typedef std::wstring nstring;
52  typedef std::wostringstream nostringstream;
53  typedef std::wistringstream nistringstream;
54  typedef wchar_t nchar;
55 #else
56  typedef std::string nstring;
57  typedef std::ostringstream nostringstream;
58  typedef std::istringstream nistringstream;
59  typedef char nchar;
60 #endif
61 
62  inline void localtime_s(struct tm* t, const time_t* time)
63  {
64 #if defined(_WIN32) && defined(__BORLANDC__)
65  ::localtime_s(time, t);
66 #elif defined(_WIN32) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
67  *t = *::localtime(time);
68 #elif defined(_WIN32)
69  ::localtime_s(t, time);
70 #else
71  ::localtime_r(time, t);
72 #endif
73  }
74 
75  inline void gmtime_s(struct tm* t, const time_t* time)
76  {
77 #if defined(_WIN32) && defined(__BORLANDC__)
78  ::gmtime_s(time, t);
79 #elif defined(_WIN32) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
80  *t = *::gmtime(time);
81 #elif defined(_WIN32)
82  ::gmtime_s(t, time);
83 #else
84  ::gmtime_r(time, t);
85 #endif
86  }
87 
88 #ifdef _WIN32
89  typedef timeb Time;
90 
91  inline void ftime(Time* t)
92  {
93  ::ftime(t);
94  }
95 #else
96  struct Time
97  {
98  time_t time;
99  unsigned short millitm;
100  };
101 
102  inline void ftime(Time* t)
103  {
104  timeval tv;
105  ::gettimeofday(&tv, NULL);
106 
107  t->time = tv.tv_sec;
108  t->millitm = static_cast<unsigned short>(tv.tv_usec / 1000);
109  }
110 #endif
111 
112  inline unsigned int gettid()
113  {
114 #ifdef _WIN32
115  return GetCurrentThreadId();
116 #elif defined(__linux__)
117  return static_cast<unsigned int>(::syscall(__NR_gettid));
118 #elif defined(__FreeBSD__)
119  long tid;
120  syscall(SYS_thr_self, &tid);
121  return static_cast<unsigned int>(tid);
122 #elif defined(__rtems__)
123  return rtems_task_self();
124 #elif defined(__APPLE__)
125  uint64_t tid64;
126  pthread_threadid_np(NULL, &tid64);
127  return static_cast<unsigned int>(tid64);
128 #endif
129  }
130 
131 #if PLOG_ENABLE_WCHAR_INPUT && !defined(_WIN32)
132  inline std::string toNarrow(const wchar_t* wstr)
133  {
134  size_t wlen = ::wcslen(wstr);
135  std::string str(wlen * sizeof(wchar_t), 0);
136 
137  if (!str.empty())
138  {
139  const char* in = reinterpret_cast<const char*>(&wstr[0]);
140  char* out = &str[0];
141  size_t inBytes = wlen * sizeof(wchar_t);
142  size_t outBytes = str.size();
143 
144  iconv_t cd = ::iconv_open("UTF-8", "WCHAR_T");
145  ::iconv(cd, const_cast<char**>(&in), &inBytes, &out, &outBytes);
146  ::iconv_close(cd);
147 
148  str.resize(str.size() - outBytes);
149  }
150 
151  return str;
152  }
153 #endif
154 
155 #ifdef _WIN32
156  inline std::wstring toWide(const char* str)
157  {
158  size_t len = ::strlen(str);
159  std::wstring wstr(len, 0);
160 
161  if (!wstr.empty())
162  {
163  int wlen = MultiByteToWideChar(codePage::kActive, 0, str, static_cast<int>(len), &wstr[0], static_cast<int>(wstr.size()));
164  wstr.resize(wlen);
165  }
166 
167  return wstr;
168  }
169 
170  inline std::string toNarrow(const std::wstring& wstr, long page)
171  {
172  std::string str(wstr.size() * sizeof(wchar_t), 0);
173 
174  if (!str.empty())
175  {
176  int len = WideCharToMultiByte(page, 0, wstr.c_str(), static_cast<int>(wstr.size()), &str[0], static_cast<int>(str.size()), 0, 0);
177  str.resize(len);
178  }
179 
180  return str;
181  }
182 #endif
183 
184  inline std::string processFuncName(const char* func)
185  {
186 #if (defined(_WIN32) && !defined(__MINGW32__)) || defined(__OBJC__)
187  return std::string(func);
188 #else
189  const char* funcBegin = func;
190  const char* funcEnd = ::strchr(funcBegin, '(');
191 
192  if (!funcEnd)
193  {
194  return std::string(func);
195  }
196 
197  for (const char* i = funcEnd - 1; i >= funcBegin; --i) // search backwards for the first space char
198  {
199  if (*i == ' ')
200  {
201  funcBegin = i + 1;
202  break;
203  }
204  }
205 
206  return std::string(funcBegin, funcEnd);
207 #endif
208  }
209 
210  inline const nchar* findExtensionDot(const nchar* fileName)
211  {
212 #ifdef _WIN32
213  return std::wcsrchr(fileName, L'.');
214 #else
215  return std::strrchr(fileName, '.');
216 #endif
217  }
218 
219  inline void splitFileName(const nchar* fileName, nstring& fileNameNoExt, nstring& fileExt)
220  {
221  const nchar* dot = findExtensionDot(fileName);
222 
223  if (dot)
224  {
225  fileNameNoExt.assign(fileName, dot);
226  fileExt.assign(dot + 1);
227  }
228  else
229  {
230  fileNameNoExt.assign(fileName);
231  fileExt.clear();
232  }
233  }
234 
236  {
237  protected:
239  {
240  }
241 
242  private:
243  NonCopyable(const NonCopyable&);
244  NonCopyable& operator=(const NonCopyable&);
245  };
246 
248  {
249  public:
250  File() : m_file(-1)
251  {
252  }
253 
254  File(const nchar* fileName) : m_file(-1)
255  {
256  open(fileName);
257  }
258 
260  {
261  close();
262  }
263 
264  off_t open(const nchar* fileName)
265  {
266 #if defined(_WIN32) && (defined(__BORLANDC__) || defined(__MINGW32__))
267  m_file = ::_wsopen(fileName, _O_CREAT | _O_WRONLY | _O_BINARY, SH_DENYWR, _S_IREAD | _S_IWRITE);
268 #elif defined(_WIN32)
269  ::_wsopen_s(&m_file, fileName, _O_CREAT | _O_WRONLY | _O_BINARY, _SH_DENYWR, _S_IREAD | _S_IWRITE);
270 #else
271  m_file = ::open(fileName, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
272 #endif
273  return seek(0, SEEK_END);
274  }
275 
276  int write(const void* buf, size_t count)
277  {
278 #ifdef _WIN32
279  return m_file != -1 ? ::_write(m_file, buf, static_cast<unsigned int>(count)) : -1;
280 #else
281  return m_file != -1 ? static_cast<int>(::write(m_file, buf, count)) : -1;
282 #endif
283  }
284 
285  template<class CharType>
286  int write(const std::basic_string<CharType>& str)
287  {
288  return write(str.data(), str.size() * sizeof(CharType));
289  }
290 
291  off_t seek(off_t offset, int whence)
292  {
293 #ifdef _WIN32
294  return m_file != -1 ? ::_lseek(m_file, offset, whence) : -1;
295 #else
296  return m_file != -1 ? ::lseek(m_file, offset, whence) : -1;
297 #endif
298  }
299 
300  void close()
301  {
302  if (m_file != -1)
303  {
304 #ifdef _WIN32
305  ::_close(m_file);
306 #else
307  ::close(m_file);
308 #endif
309  m_file = -1;
310  }
311  }
312 
313  static int unlink(const nchar* fileName)
314  {
315 #ifdef _WIN32
316  return ::_wunlink(fileName);
317 #else
318  return ::unlink(fileName);
319 #endif
320  }
321 
322  static int rename(const nchar* oldFilename, const nchar* newFilename)
323  {
324 #ifdef _WIN32
325  return MoveFileW(oldFilename, newFilename);
326 #else
327  return ::rename(oldFilename, newFilename);
328 #endif
329  }
330 
331  private:
332  int m_file;
333  };
334 
336  {
337  public:
339  {
340 #ifdef _WIN32
341  InitializeCriticalSection(&m_sync);
342 #elif defined(__rtems__)
343  rtems_semaphore_create(0, 1,
344  RTEMS_PRIORITY |
345  RTEMS_BINARY_SEMAPHORE |
346  RTEMS_INHERIT_PRIORITY, 1, &m_sync);
347 #else
348  ::pthread_mutex_init(&m_sync, 0);
349 #endif
350  }
351 
353  {
354 #ifdef _WIN32
355  DeleteCriticalSection(&m_sync);
356 #elif defined(__rtems__)
357  rtems_semaphore_delete(m_sync);
358 #else
359  ::pthread_mutex_destroy(&m_sync);
360 #endif
361  }
362 
363  friend class MutexLock;
364 
365  private:
366  void lock()
367  {
368 #ifdef _WIN32
369  EnterCriticalSection(&m_sync);
370 #elif defined(__rtems__)
371  rtems_semaphore_obtain(m_sync, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
372 #else
373  ::pthread_mutex_lock(&m_sync);
374 #endif
375  }
376 
377  void unlock()
378  {
379 #ifdef _WIN32
380  LeaveCriticalSection(&m_sync);
381 #elif defined(__rtems__)
382  rtems_semaphore_release(m_sync);
383 #else
384  ::pthread_mutex_unlock(&m_sync);
385 #endif
386  }
387 
388  private:
389 #ifdef _WIN32
390  CRITICAL_SECTION m_sync;
391 #else
392  pthread_mutex_t m_sync;
393 #endif
394  };
395 
397  {
398  public:
399  MutexLock(Mutex& mutex) : m_mutex(mutex)
400  {
401  m_mutex.lock();
402  }
403 
405  {
406  m_mutex.unlock();
407  }
408 
409  private:
410  Mutex& m_mutex;
411  };
412 
413  template<class T>
415  {
416  public:
418  {
419  assert(!m_instance);
420  m_instance = static_cast<T*>(this);
421  }
422 
424  {
425  assert(m_instance);
426  m_instance = 0;
427  }
428 
429  static T* getInstance()
430  {
431  return m_instance;
432  }
433 
434  private:
435  static T* m_instance;
436  };
437 
438  template<class T>
439  T* Singleton<T>::m_instance = NULL;
440  }
441 }
Definition: AndroidAppender.h:5
Definition: Util.h:247
Definition: Util.h:414
MutexLock(Mutex &mutex)
Definition: Util.h:399
off_t seek(off_t offset, int whence)
Definition: Util.h:291
Definition: Util.h:235
unsigned short millitm
Definition: Util.h:99
std::string processFuncName(const char *func)
Definition: Util.h:184
File(const nchar *fileName)
Definition: Util.h:254
File()
Definition: Util.h:250
void close()
Definition: Util.h:300
void splitFileName(const nchar *fileName, nstring &fileNameNoExt, nstring &fileExt)
Definition: Util.h:219
time_t time
Definition: Util.h:98
void localtime_s(struct tm *t, const time_t *time)
Definition: Util.h:62
static int rename(const nchar *oldFilename, const nchar *newFilename)
Definition: Util.h:322
int write(const std::basic_string< CharType > &str)
Definition: Util.h:286
char nchar
Definition: Util.h:59
Definition: Util.h:335
void gmtime_s(struct tm *t, const time_t *time)
Definition: Util.h:75
std::ostringstream nostringstream
Definition: Util.h:57
int write(const void *buf, size_t count)
Definition: Util.h:276
~Mutex()
Definition: Util.h:352
~Singleton()
Definition: Util.h:423
static int unlink(const nchar *fileName)
Definition: Util.h:313
std::istringstream nistringstream
Definition: Util.h:58
std::string nstring
Definition: Util.h:56
off_t open(const nchar *fileName)
Definition: Util.h:264
Definition: Util.h:396
unsigned int gettid()
Definition: Util.h:112
Singleton()
Definition: Util.h:417
Definition: Util.h:96
void ftime(Time *t)
Definition: Util.h:102
const nchar * findExtensionDot(const nchar *fileName)
Definition: Util.h:210
Mutex()
Definition: Util.h:338
NonCopyable()
Definition: Util.h:238
~MutexLock()
Definition: Util.h:404
static T * getInstance()
Definition: Util.h:429
~File()
Definition: Util.h:259