VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
UbSystem.h
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
33//=======================================================================================
34#ifndef UBSYSTEM_H
35#define UBSYSTEM_H
36
37#if defined(_WIN32) || defined(_WIN64)
38#define UBSYSTEM_WINDOWS
39#include <direct.h>
40#include <io.h>
41#include <process.h>
42//#ifndef _WINSOCK2API_ //ansonsten gibt es mecker bei #include "Windows.h" und ::Sleep()
43// #define _WINSOCK2API_
44// #include<WinSock2.h>
45//#endif
46#include <windows.h>
47//#include <Windows.h>
48//#include <tchar.h>
49#elif defined(__APPLE__)
50#define UBSYSTEM_APPLE
51#include "dirent.h"
52#include "sys/stat.h"
53#include <sys/stat.h>
54#include <sys/syscall.h>
55#include <unistd.h>
56#elif (defined(__amd64) || defined(__amd64__) || defined(__unix__)) && !defined(__AIX__)
57#define UBSYSTEM_LINUX
58#include "dirent.h"
59#include <cstring>
60#include <sys/stat.h>
61#include <unistd.h>
62#elif defined(__AIX__)
63#define UBSYSTEM_AIX
64#include "dirent.h"
65#include <sys/stat.h>
66#include <sys/types.h>
67#include <unistd.h>
68#else
69#error "ub_system::UnknownMachine"
70#endif
71
72#if defined(__unix__) && defined(__CYGWIN__)
73#define UBSYSTEM_CYGWIN
74#include <windows.h>
75#elif defined(__unix__)
76#include <sys/syscall.h>
77#endif
78
79#if defined(min) || defined(max) // daruch kann man sich spaeter #undef min; #undef max erparen
80#error add NOMINMAX to preprocessor defines
81#endif
82
83#include <algorithm>
84#include <cctype> //for toupper
85#include <ctime>
86#include <iomanip>
87#include <iostream>
88#include <sstream>
89#include <string>
90#include <typeinfo>
91
94
95#if defined(CAB_BOOST)
96#include <boost/thread.hpp>
97#endif // CAB_BOOST
98
99// DEFINE TO STRING
100// e.g. #define FOO hallo
101// -> QUOTEME(FOO) == "hallo"
102#define _QUOTEME(x) #x
103#define QUOTEME(x) _QUOTEME(x)
104
105// allg.:
106// const int * C1 -> C1 is variable pointer to a constant integer
107// int const * C2 -> C2 is variable pointer to a constant integer (same as above)
108// int * const C3 -> C3 is constant pointer to a variable integer
109// int const * const C4 -> C4 is constant pointer to a constant integer
110
112// ub_system
114namespace ub_system
115{
116template <bool>
117struct ub_static_assert; // deklaration (ub_xxx da static_assert in C++0x ein keyword werden wird)
118template <>
120}; // deklaration + definition der spezialisierung fuer "true"
121 // ub_static_assert<false> fuehrt zu compiler fehler, da dafuer
122 // keine implementierung vorhanden! //UB_STATIC_ASSERT(false)
123
124/*==========================================================*/
125inline void sleepMs(const unsigned int &msec)
126{
127#if defined(UBSYSTEM_WINDOWS)
128 ::Sleep((msec == 0) ? 1 : msec); // +1 here causes a context switch if SleepMSec(0) is called
129#elif (defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)) && !defined(UBSYSTEM_CYGWIN)
130 ::usleep(1000 * msec);
131#elif defined(UBSYSTEM_CYGWIN)
132 ::Sleep((msec == 0) ? 1 : msec);
133#else
134#error "ub_system::sleepMSec - UnknownMachine"
135#endif
136}
137/*==========================================================*/
138inline void sleepS(const unsigned int &sec)
139{
140#if defined(UBSYSTEM_WINDOWS) || defined(UBSYSTEM_CYGWIN)
141 ::Sleep((sec == 0) ? 1 : sec * 1000); // +1 here causes a context switch if sleepS(0) is called
142#elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX) && !defined(UBSYSTEM_CYGWIN)
143 ::sleep(sec);
144#else
145#error "ub_system::sleepS - UnknownMachine"
146#endif
147}
148/*==========================================================*/
149// checks if the bits of bitmask are set in value
150template <typename T>
151inline bool bitCheck(const T &value, const T &bitmask)
152{
153 return ((value & bitmask) == bitmask);
154}
155/*==========================================================*/
156// checks if the bits of bitmask are set in value
157template <typename T>
158inline void setBit(T &value, const T &bitmask)
159{
160 value |= bitmask;
161}
162/*==========================================================*/
163template <typename T>
164inline void unsetBit(T &value, const T &bitmask)
165{
166 value &= ~bitmask;
167}
168/*==========================================================*/
169// returns bitmask as string e.g. 0001 0100 1101
170template <typename T>
171inline std::string getBitString(const T &value)
172{
173 std::stringstream text;
174 for (int i = sizeof(value) * 8 - 1 /*8 bits per byte*/; i >= 0; i--) {
175 text << (char)(((value >> i) & 1) + '0');
176 if (i % 4 == 0 && i > 0)
177 text << ' ';
178 }
179 return text.str();
180}
181/*==========================================================*/
182// converts string to type T
183// usage: int x = stringTo<int>("123");
184template <typename T>
185inline T stringTo(const std::string &s)
186{
187 std::istringstream iss(s);
188 T x;
189 iss >> x;
190 if (!iss)
191 UB_THROW(UbException(UB_EXARGS, " cannot convert \"" + s + "\" to type <" +
192 static_cast<std::string>(typeid(x).name()) + ">"));
193
194 return x;
195}
196/*==========================================================*/
197// usage: string s = toString(x);
198template <typename T>
199inline std::string toString(const T &x, int precision = 15)
200{
201 std::ostringstream oss;
202 oss << std::setprecision(precision);
203 oss << x;
204 return oss.str();
205}
206/*==========================================================*/
207// e.g. str="iHcsnW" -> "IHCSNW"
208inline std::string toUpperString(const std::string &str)
209{
210 std::string tmp(str);
211 std::transform(tmp.begin(), tmp.end(), tmp.begin(), static_cast<int (*)(int)>(std::toupper));
212
213 return tmp;
214}
215/*==========================================================*/
216// e.g. str="iHcsnW" -> "ihcsnw"
217inline std::string toLowerString(const std::string &str)
218{
219 std::string tmp(str);
220 std::transform(tmp.begin(), tmp.end(), tmp.begin(), static_cast<int (*)(int)>(std::tolower));
221
222 return tmp;
223}
224/*==========================================================*/
225// usage: std::string s = replaceInString(str,"\\","/");
226// std::string s = replaceInString(str,"ich","du");
227static std::string replaceInString(std::string original, const std::string &replace, const std::string &replaceWith)
228{
229 size_t pos = 0;
230 while ((pos = original.find(replace, pos)) != std::string::npos) {
231 original.replace(pos, replace.size(), replaceWith);
232 pos += replaceWith.size();
233 }
234 return original;
235}
236/*==========================================================*/
237// returns content of an enviroment variable
238inline std::string getEnv(const std::string &var)
239{
240 char *str = getenv(var.c_str());
241 if (str == NULL) {
242 return std::string("");
243 }
244
245 return static_cast<std::string>(str);
246}
247/*==========================================================*/
248inline bool isDirectory(const std::string &dir, const unsigned & /*attemptions*/ = 3)
249{
250 if (dir.empty())
251 UB_THROW(UbException(UB_EXARGS, "dir is empty"));
252
253 std::string path = ub_system::replaceInString(dir, "\\", "/");
254
255#if defined UBSYSTEM_WINDOWS
256#ifndef _UNICODE
257 if (_access(path.c_str(), 0) == -1)
258 return false;
259#else
260 if (_waccess(path.c_str(), 0) == -1)
261 return false;
262#endif
263#elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)
264 struct stat stFileInfo;
265 if (stat(path.c_str(), &stFileInfo) != 0) {
266 return false;
267 }
268#endif
269
270 return true;
271}
272/*==========================================================*/
273// usage: makeDirectory("c:/temp");
274// makeDirectory("c:/temp/");
275// return: true -> successful
276// false -> failed
277#if defined(CAB_BOOST)
278static boost::mutex mtx_makeDirectory;
279#endif
280inline bool makeDirectory(const std::string &dir)
281{
282 UBLOG(logDEBUG5, "ub_system::makeDirectory - start, dir=" << dir);
283
284 if (dir.empty())
285 UB_THROW(UbException(UB_EXARGS, "dir is empty"));
286 std::string path = ub_system::replaceInString(dir, "\\", "/");
287
288 bool dirCreated = true;
289
290 if (path[path.size() - 1] != '/')
291 path += "/";
292 size_t pos = 0;
293
294 while ((pos = path.find("/", pos + 1)) != std::string::npos) {
295 std::string tmpdir = path.substr(0, pos);
296#if defined(CAB_BOOST)
297 boost::mutex::scoped_lock lock(mtx_makeDirectory);
298#endif
299#if defined UBSYSTEM_WINDOWS
300 if (
302 _access(tmpdir.c_str(), 0) == -1 && _mkdir(tmpdir.c_str()) == -1
303#else
304 _waccess(tmpdir.c_str(), 0) == -1 && _wmkdir(tmpdir.c_str()) == -1
305#endif
306 ) {
307 UBLOG(logDEBUG5, "ub_system::makeDirectory - dir=\"" << tmpdir << "\" - doesn't exist or makedir failed");
308 dirCreated = false;
309 break;
310 }
311#elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)
312 int status = mkdir(tmpdir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
313 if (status == 0) {
314 UBLOG(logDEBUG5,"ub_system::makeDirectory - dir=\"" << tmpdir << " - directory created successfully.");
315 dirCreated = true;
316 } else {
317 UBLOG(logDEBUG5,"ub_system::makeDirectory - dir=\"" << tmpdir << " - mkdir() failed" << " ERROR: " << strerror(errno));
318 dirCreated = false;
319 }
320#else
321#error "ub_system::makeDirectory - UnknownMachine"
322#endif
323 }
324 return dirCreated;
325}
326/*==========================================================*/
327#if defined(CAB_BOOST)
328static boost::mutex mtx_removeDirectory;
329#endif
330inline int removeDirectory(const std::string &dir)
331{
332#if defined(CAB_BOOST)
333 boost::mutex::scoped_lock lock(mtx_removeDirectory);
334#endif
335 std::string command = "rmdir \"" + dir + "\"";
336 return std::system(command.c_str());
337}
338/*==========================================================*/
339// usage : getPathFromString("c:/temp/foo.txt");
340// returns: "c:/temp"
341// usage : getPathFromString("c:\\temp\\foo.txt");
342// returns: "c:/temp"
343// usage : getPathFromString("foo.txt");
344// returns: ""
345inline std::string getPathFromString(const std::string &fileStringWithPath)
346{
347 std::string tmp = ub_system::replaceInString(fileStringWithPath, "\\", "/");
348 std::size_t last = tmp.rfind("/");
349 if (last != std::string::npos)
350 tmp.resize(last);
351 else
352 tmp = "";
353 return tmp;
354}
355/*==========================================================*/
356// usage : getFilenameFromString("c:/temp/foo.txt");
357// returns: "foo.txt"
358// usage : getFilenameFromString("c:/temp/foo.txt",false);
359// returns: "foo"
360// usage : getFilenameFromString("c:/temp/");
361// returns: ""
362inline std::string getFilenameFromString(const std::string &fileStringWithPath, bool withExtension = true)
363{
364 std::string tmp = ub_system::replaceInString(fileStringWithPath, "\\", "/");
365
366 // remove path
367 std::size_t last = tmp.rfind("/");
368 if (last != std::string::npos && (last + 1) < tmp.size())
369 tmp.erase(0, last + 1);
370
371 // remove extension
372 if (!withExtension) {
373 last = tmp.rfind(".");
374 if (last != std::string::npos)
375 tmp.erase(last);
376 }
377
378 return tmp;
379}
380/*==========================================================*/
381inline int getProcessID()
382{
383#if defined UBSYSTEM_WINDOWS
384 return _getpid();
385#elif defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)
386 return getpid();
387#else
388#error "int ub_system::getProcessID() - UnknownMachine"
389#endif
390}
391/*==========================================================*/
392inline unsigned long getCurrentThreadID()
393{
394#if defined UBSYSTEM_WINDOWS || defined(UBSYSTEM_CYGWIN)
395 return (unsigned long)GetCurrentThreadId();
396#elif defined(UBSYSTEM_APPLE)
398 pthread_threadid_np(nullptr, &tid);
399 return (unsigned long)tid;
400#elif defined(UBSYSTEM_LINUX)
401 return (unsigned long)syscall(SYS_gettid);
402#elif defined(UBSYSTEM_AIX)
403 return (unsigned long)getpid(); // WORKAROUND for IBM (for get thread id is another function necessary)
404#else
405#error "unsigned long ub_system::getCurrentThreadID() - UnknownMachine"
406#endif
407}
408/*==========================================================*/
409inline bool isBigEndian()
410{
411 short word = 0x4321;
412 if ((*(char *)&word) != 0x21)
413 return true;
414 else
415 return false;
416}
417/*==========================================================*/
418inline bool isLittleEndian() { return !isBigEndian(); }
419/*==========================================================*/
420inline std::string getTimeStamp()
421{
422 time_t t = time(NULL);
423 tm *localTime = localtime(&t);
424
425 std::stringstream tmp;
426 tmp.fill('0');
427
428 tmp << localTime->tm_year + 1900 << "." << std::setw(2) << localTime->tm_mon + 1 << "." << std::setw(2)
429 << localTime->tm_mday << "@" << std::setw(2) << localTime->tm_hour << "." << std::setw(2) << localTime->tm_min
430 << "." << std::setw(2) << localTime->tm_sec;
431
432 return tmp.str();
433}
434/*==========================================================*/
435// swap Byte Order
436// usage: int test = 8;
437// swapByteOrder((unsigned char*)& test, sizeof(int))
438//#define ByteSwap5(x) ByteSwap((unsigned char *) &x,sizeof(x))
439inline void swapByteOrder(unsigned char *toSwap, int length)
440{
441 int i = 0;
442 int j = length - 1;
443 while (i < j) {
444 std::swap(toSwap[i], toSwap[j]);
445 i++, j--;
446 }
447}
449// get host name
450inline std::string getMachineName()
451{
452 char Name[150];
453
454#if defined(UBSYSTEM_WINDOWS) || defined(UBSYSTEM_CYGWIN)
455 TCHAR infoBuf[150];
456 DWORD bufCharCount = 150;
457 memset(Name, 0, 150);
459 for (int i = 0; i < 150; i++) {
460 Name[i] = infoBuf[i];
461 }
462 } else {
463 strcpy_s(Name, "Unknown_Host_Name");
464 }
465#elif (defined(UBSYSTEM_LINUX) || defined(UBSYSTEM_APPLE) || defined(UBSYSTEM_AIX)) && !defined(UBSYSTEM_CYGWIN)
466 memset(Name, 0, 150);
467 gethostname(Name, 150);
468#endif
469 return std::string(Name);
470}
471
473// generic IfThenElse - start
475// primary template: yield second or third argument depending on first argument
476template <bool C, typename Ta, typename Tb>
478
479// partial specialization: true yields second argument
480template <typename Ta, typename Tb>
481class IfThenElse<true, Ta, Tb>
482{
483public:
484 using ResultT = Ta;
485};
486
487// partial specialization: false yields third argument
488template <typename Ta, typename Tb>
489class IfThenElse<false, Ta, Tb>
490{
491public:
492 using ResultT = Tb;
493};
495// generic IfThenElse - end
497
499// help struct for overloading methods in template classes for specific types
501template <typename T>
502struct type2type {
503 using type = T;
504};
505
507// pair selector
509template <typename Pair>
510struct select1st {
512 using result_type = typename Pair::first_type;
513
514 const result_type &operator()(const argument_type &p) const { return p.first; }
515};
516
517template <typename Pair>
518struct select2nd {
520 using result_type = typename Pair::second_type;
521
522 const result_type &operator()(const argument_type &p) const { return p.second; }
523};
524
525} // namespace ub_system
526
527#define UB_STATIC_ASSERT(expr) static_cast<void>(sizeof(ub_system::ub_static_assert<expr>));
528// zum ueberpruefen von STATISCHEN ausdruecken waehrend der compile-zeit
529//--> Ausdruecke muessen schon ZUR compilerzeit auswertbar sein !!!
530// Anwendung z.B. zur Ueberpruefung von Funktionalitaeten, wie z.B. bei UbMath::getNegativeInfinity<double>();
531//
532// Grund fuer macro ist einfach, dass es besser anzuwenden ist in der praxis!
533// ansonsten wuerde es so aussehen:
534// ub_system::ub_static_assert< aaa == 1 > test();
535// da ist UB_STATIC_ASSERT(aaa == 1); schoener
536//
537// um das zu vermeiden machtman hier diesen static_cast<void>(sizeof(...) )
538// Code-Snippet:
539// struct Test { const static bool m_const_bool = true; bool m_bool; };
540// int main() {
541// UB_STATIC_ASSERT( Test::m_const_bool == true );
542// --> okay, assert bestanden
543// UB_STATIC_ASSERT( Test::m_const_bool == false); //:
544// --> assert nicht bestanden z.B. error C2027: use of undefined type 'ub_system::ub_static_assert<__formal> with
545// __formal = false --> funzt nicht. fehler im code UB_STATIC_ASSERT( Test::m_bool == true );
546// --> nicht erlaubt, da m_bool nicht statisch und nicht const ist.
547//}
548
549#endif // UBSYSTEM_H
550
std::shared_ptr< T > SPtr
@ x
Definition Axis.h:42
#define UB_THROW(e)
Definition UbException.h:78
#define UBLOG(level, logtext)
Definition UbLogger.h:327
#define UB_EXARGS
Definition UbException.h:73
@ logDEBUG5
Definition UbLogger.h:54
std::string toUpperString(const std::string &str)
Definition UbSystem.h:208
unsigned long getCurrentThreadID()
Definition UbSystem.h:392
void unsetBit(T &value, const T &bitmask)
Definition UbSystem.h:164
bool makeDirectory(const std::string &dir)
Definition UbSystem.h:280
void setBit(T &value, const T &bitmask)
Definition UbSystem.h:158
std::string toString(const T &x, int precision=15)
Definition UbSystem.h:199
std::string getBitString(const T &value)
Definition UbSystem.h:171
int removeDirectory(const std::string &dir)
Definition UbSystem.h:330
std::string getTimeStamp()
Definition UbSystem.h:420
bool isDirectory(const std::string &dir, const unsigned &=3)
Definition UbSystem.h:248
void sleepMs(const unsigned int &msec)
Definition UbSystem.h:125
void sleepS(const unsigned int &sec)
Definition UbSystem.h:138
std::string toLowerString(const std::string &str)
Definition UbSystem.h:217
std::string getMachineName()
Definition UbSystem.h:450
bool isBigEndian()
Definition UbSystem.h:409
std::string getPathFromString(const std::string &fileStringWithPath)
Definition UbSystem.h:345
void swapByteOrder(unsigned char *toSwap, int length)
Definition UbSystem.h:439
T stringTo(const std::string &s)
Definition UbSystem.h:185
bool bitCheck(const T &value, const T &bitmask)
Definition UbSystem.h:151
bool isLittleEndian()
Definition UbSystem.h:418
int getProcessID()
Definition UbSystem.h:381
std::string getEnv(const std::string &var)
Definition UbSystem.h:238
std::string getFilenameFromString(const std::string &fileStringWithPath, bool withExtension=true)
Definition UbSystem.h:362
const result_type & operator()(const argument_type &p) const
Definition UbSystem.h:514
typename Pair::first_type result_type
Definition UbSystem.h:512
typename Pair::second_type result_type
Definition UbSystem.h:520
const result_type & operator()(const argument_type &p) const
Definition UbSystem.h:522