basic.h
Go to the documentation of this file.
1/*!
2 * \file basic.h
3 * \brief Basic definitions.
4 * Part of the Common Cross-platform Geographic Library (CCGL)
5 *
6 * \remarks
7 * - 1. 2018-05-02 - lj - Initially implementation.
8 * - 2. 2018-06-21 - lj - Test on Intel C++ compiler.
9 * - 3. 2018-08-21 - lj - Doxygen comment style check.
10 *
11 * \author Liangjun Zhu, zlj(at)lreis.ac.cn
12 * \version 1.1
13 */
14#ifndef CCGL_BASIC_H
15#define CCGL_BASIC_H
16
17/*! `NDEBUG` or `_DEBUG` mean not build on `DEBUG` mode. */
18#ifndef NDEBUG
19#ifndef _DEBUG
20#define _DEBUG
21#endif /* _DEBUG */
22#endif /* NDEBUG */
23
24/*! A reference to x64 architecture */
25#if defined(_WIN64) || defined(__x86_64) || defined(__LP64__)
26#define CPP_64
27#endif
28
29/*! A reference to MSVC environment */
30#if defined _MSC_VER
31#define CPP_MSVC
32#endif /* _MSC_VER */
33
34/*! A reference to Intel C++ compiler */
35#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC)
36#define CPP_ICC
37#endif /* __INTEL_COMPILER */
38
39/*! A reference to GCC compiler */
40#if defined(__GNUC__)
41#define CPP_GCC
42/*! A reference to GCC compiler on macOS */
43#if defined(__APPLE__)
44#define CPP_APPLE
45#endif /* __APPLE__ */
46#endif /* __GNUC__ */
47
48#include <stdint.h>
49#include <memory>
50#include <stdexcept>
51#include <cfloat>
52#include <map>
53#include <string>
54#include <cstring> // strcasecmp in GCC
55/// platform
56#if defined WINDOWS
57// For MSVC and MINGW64 in Windows OS
58// #define _WINSOCKAPI_ // In order to stop windows.h including winsock.h
59// _WINSOCKAPI_ is defined by <winsock2.h>
60#include <winsock2.h>
61#include <windows.h>
62#endif /* WINDOWS */
63
64#if defined CPP_GCC
65#include <dirent.h>
66#include <unistd.h>
67#include <sys/types.h>
68#include <sys/stat.h>
69#include <sys/time.h>
70#include <fcntl.h>
71#include <cerrno>
72#endif /* CPP_GCC */
73
74using std::string;
75
76// define some macro for string related built-in functions
77#ifdef CPP_MSVC
78#define stringcat strcat_s
79#define stringcpy strcpy_s
80#define strprintf sprintf_s
81#define stringtoken strtok_s
82#define stringscanf sscanf_s
83#else
84#define stringcat strcat
85#define stringcpy strcpy
86#define strprintf snprintf
87#define stringtoken strtok_r
88#define stringscanf sscanf
89#endif /* CPP_MSVC */
90
91#if defined(__MINGW32_MAJOR_VERSION) || defined(__MINGW64_VERSION_MAJOR)
92#define MINGW
93#endif
94
95#if defined(MINGW) || defined(_MSC_VER)
96#define strcasecmp _stricmp
97#endif /* MINGW or MSVC */
98
99#if defined(__clang__) && defined(__apple_build_version__)
100// Apple Clang
101#if ((__clang_major__ * 100) + __clang_minor__) >= 400
102#if __has_feature(cxx_noexcept)
103#define HAS_NOEXCEPT
104#endif /* NOEXCEPT */
105#if __has_feature(cxx_override_control)
106#define HAS_OVERRIDE
107#endif /* OVERRIDE */
108#endif /* Apple Clang */
109#elif defined(__clang__)
110// Clang
111#if ((__clang_major__ * 100) + __clang_minor__) >= 304
112#if __has_feature(cxx_noexcept)
113#define HAS_NOEXCEPT
114#endif /* NOEXCEPT */
115#if __has_feature(cxx_override_control)
116#define HAS_OVERRIDE
117#endif /* OVERRIDE */
118#if __has_feature(cxx_variadic_templates)
119#define HAS_VARIADIC_TEMPLATES
120#endif /* VARIADIC_TEMPLATES */
121#endif /* Clang */
122#elif defined(CPP_ICC)
123// Intel C++
124#if ((__INTEL_COMPILER >= 1400) && (__INTEL_COMPILER != 9999)) || (__ICL >= 1400)
125#define HAS_NOEXCEPT
126#define HAS_OVERRIDE
127#define HAS_VARIADIC_TEMPLATES
128#endif /* Intel C++ */
129#elif defined(CPP_GCC)
130// GNU GCC
131#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && (__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__))
132#define HAS_NOEXCEPT
133#define HAS_OVERRIDE
134#define HAS_VARIADIC_TEMPLATES
135#endif /* GCC */
136#elif defined(_MSC_VER)
137// MS Visual C++
138#if _MSC_VER >= 1900
139#define HAS_NOEXCEPT
140#endif /* Visual Studio 2015 or later */
141#if _MSC_VER >= 1800
142#define HAS_VARIADIC_TEMPLATES
143#endif /* Visual Studio 2013 or later */
144#if _MSC_VER>= 1600
145#define HAS_OVERRIDE
146#endif /* Visual Studio 2010 or later */
147#endif /* Figure out HAS_NOEXCEPT, HAS_VARIADIC_TEMPLATES, and HAS_OVERRIDE or not */
148
149/*! A compatible reference to `noexcept` or `throw()` if not supported by the compiler. */
150#ifdef HAS_NOEXCEPT
151#define NOEXCEPT noexcept
152#else
153#define NOEXCEPT throw()
154#endif /* HAS_NOEXCEPT */
155
156/*! A compatible reference to `override` or blank if not supported by the compiler. */
157#ifdef HAS_OVERRIDE
158#define OVERRIDE override
159#else
160#define OVERRIDE
161#endif /* HAS_OVERRIDE */
162
163/*
164* Avoid the compile error on MSVC like this:
165* warning C4251: 'CLASS_TEST::m_structs':
166* class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class
167* refers to http://www.cnblogs.com/duboway/p/3332057.html
168*/
169#ifdef MSVC
170#define DLL_STL_LIST(STL_API, STL_TYPE) \
171 template class STL_API std::allocator< STL_TYPE >; \
172 template class STL_API std::vector<STL_TYPE, std::allocator< STL_TYPE > >;
173#endif /* MSVC */
174
175#ifdef USE_GDAL
176/* Ignore warning on Windows MSVC compiler caused by GDAL.
177* refers to http://blog.csdn.net/liminlu0314/article/details/8227518
178*/
179#if defined(_MSC_VER) && (_MSC_VER >= 1400)
180#pragma warning(disable: 4100 4190 4251 4275 4305 4309 4819 4996)
181#endif /* Ignore warnings of GDAL */
182#endif /* USE_GDAL */
183
184/*!
185 * \namespace ccgl
186 * \brief Common Cross-platform Geographic Library (CCGL)
187 */
188namespace ccgl {
189#if defined CPP_MSVC
190/// x86 and x64 Compatibility
191/// 1-byte (8-bit) signed integer
192typedef signed __int8 vint8_t;
193/// 1-byte (8-bit) unsigned integer
194typedef unsigned __int8 vuint8_t;
195/// 2-byte (16-bit) signed integer
196typedef signed __int16 vint16_t;
197/// 2-byte (16-bit) unsigned integer
198typedef unsigned __int16 vuint16_t;
199/// 4-byte (32-bit) signed integer
200typedef signed __int32 vint32_t;
201/// 4-byte (32-bit) unsigned integer
202typedef unsigned __int32 vuint32_t;
203/// 8-byte (64-bit) signed integer
204typedef signed __int64 vint64_t;
205/// 8-byte (64-bit) unsigned integer
206typedef unsigned __int64 vuint64_t;
207#else
208typedef int8_t vint8_t;
209typedef uint8_t vuint8_t;
210typedef int16_t vint16_t;
211typedef uint16_t vuint16_t;
212typedef int32_t vint32_t;
213typedef uint32_t vuint32_t;
214typedef int64_t vint64_t;
215typedef uint64_t vuint64_t;
216#endif
217
218#ifdef _WIN32
219/*! Format of integers */
220#define LLD "%I64d"
221#define LLU "%I64u"
222#else
223#define LLD "%lld"
224#define LLU "%llu"
225#endif
226
227#ifdef CPP_64
228typedef vint64_t vint;
229typedef vint64_t vsint;
230typedef vuint64_t vuint;
231#else
232typedef vint32_t vint;
233typedef vint32_t vsint;
234typedef vuint32_t vuint;
235#endif
236/// Signed integer representing position.
237typedef vint64_t pos_t;
238
239///
240/// Global utility definitions
241///
242
243/*! Default NoData value for raster data etc. */
244#ifndef NODATA_VALUE
245#define NODATA_VALUE (-9999.)
246#endif /* NODATA_VALUE */
247
248/*! Missing float value */
249#ifndef MISSINGFLOAT
250#define MISSINGFLOAT (-1 * FLT_MAX)
251#endif /* MISSINGFLOAT */
252
253/*! Maximum float value */
254#ifndef MAXIMUMFLOAT
255#define MAXIMUMFLOAT FLT_MAX
256#endif /* MAXIMUMFLOAT */
257
258/*! Maximum length of full file path */
259#ifndef PATH_MAX
260#define PATH_MAX 1024
261#endif /* PATH_MAX */
262
263/*! A approximation of Zero */
264#ifndef UTIL_ZERO
265#define UTIL_ZERO 1.0e-6
266#endif /* UTIL_ZERO */
267
268/*! A approximation of PI */
269#ifndef PI
270#define PI 3.14159265358979323846
271#endif /* PI */
272
273/*! Minimum slope(radian) value */
274#ifndef MINI_SLOPE
275#define MINI_SLOPE 0.0001
276#endif /* MINI_SLOPE */
277
278#ifdef MSVC
279#if _MSC_VER <= 1600
280#define isnan(x) ((x) != (x))
281#define isinf(x) (!_finite(x) && !_isnan(x))
282#endif
283#endif
284
285#ifdef WINDOWS
286#define SEP '\\'
287#define SEPSTR "\\"
288#ifndef MSVC
289#define LIBPREFIX "lib"
290#endif
291#define LIBSUFFIX ".dll"
292#else
293#define SEP '/'
294#define SEPSTR "/"
295#define LIBPREFIX "lib"
296#endif /* Windows */
297#ifdef LINUX
298#define LIBSUFFIX ".so"
299#elif defined(MACOS) || defined(MACOSX)
300#define LIBSUFFIX ".dylib"
301#endif /* Linux and macOS */
302
303/*! A reference to the postfix of executable file for DEBUG mode */
304#ifdef _DEBUG
305#define POSTFIX "d"
306#endif
307/*! A reference to the postfix of executable file for RELWITHDEBINFO mode */
308#ifdef RELWITHDEBINFO
309#define POSTFIX "rd"
310#endif
311/*! A reference to the postfix of executable file for MINSIZEREL mode */
312#ifdef MINSIZEREL
313#define POSTFIX "s"
314#endif
315/*! A reference to the postfix of executable file for RELEASE mode */
316#ifndef POSTFIX
317#define POSTFIX ""
318#endif
319
320///
321/// Use static_cast<T>(a) instead (T)a or T(a) to convert datetypes
322///
323
324/*! Convert to integer `int` */
325#define CVT_INT(param) static_cast<int>((param))
326/*! Convert to size_t `size_t` */
327#define CVT_SIZET(param) static_cast<size_t>((param))
328/*! Convert to float `float` */
329#define CVT_FLT(param) static_cast<float>((param))
330/*! Convert to double `double` */
331#define CVT_DBL(param) static_cast<double>((param))
332/*! Convert to time_t `time_t` */
333#define CVT_TIMET(param) static_cast<time_t>((param))
334/*! Convert to char `char` */
335#define CVT_CHAR(param) static_cast<char>((param))
336/*! Convert to string `string` */
337#define CVT_STR(param) static_cast<string>((param))
338
339/*! Convert to 8-byte (64-bit) signed integer `vint` */
340#define CVT_VINT(param) static_cast<vint>((param))
341/*! Convert to 8-byte (64-bit) signed integer `vsint` */
342#define CVT_VSINT(param) static_cast<vsint>((param))
343/*! Convert to 8-byte (64-bit) unsigned integer `vuint` */
344#define CVT_VUINT(param) static_cast<vuint>((param))
345/*! Convert to 8-byte (64-bit) unsigned integer `vuint64_t` */
346#define CVT_VUINT64(param) static_cast<vuint64_t>((param))
347
348/*! Map of string key and string value */
349typedef std::map<string, string> STRING_MAP;
350
351/*! Map of string key and double value */
352typedef std::map<string, double> STRDBL_MAP;
353
354#ifdef CPP_64
355#define ITOA_S _i64toa_s
356#define ITOW_S _i64tow_s
357#define I64TOA_S _i64toa_s
358#define I64TOW_S _i64tow_s
359#define UITOA_S _ui64toa_s
360#define UITOW_S _ui64tow_s
361#define UI64TOA_S _ui64toa_s
362#define UI64TOW_S _ui64tow_s
363#else
364#define ITOA_S _itoa_s
365#define ITOW_S _itow_s
366#define I64TOA_S _i64toa_s
367#define I64TOW_S _i64tow_s
368#define UITOA_S _ui64toa_s
369#define UITOW_S _ui64tow_s
370#define UI64TOA_S _ui64toa_s
371#define UI64TOW_S _ui64tow_s
372#endif
373
374/*!
375 * \class NotCopyable
376 * \brief Base class for classes that cannot be copied. By inheriting this
377 * class you can disable copying of your classes.
378 *
379 * \code
380 * class myClass: private NotCopyable {}
381 * // or
382 * class myClass: NotCopyable {}
383 * \endcode
384 */
386private:
387 NotCopyable(const NotCopyable&);
388
389 NotCopyable& operator=(const NotCopyable&);
390public:
391 NotCopyable();
392};
393
394/*!
395 * \class Object
396 * \brief Base of all classes.
397 */
398class Object {
399public:
400 virtual ~Object();
401};
402
403/*!
404 * \class Interface
405 * \brief Base type of all interfaces. All interface types are encouraged to be virtual inherited.
406 */
408public:
409 virtual ~Interface();
410};
411
412/*!
413 * \class ModelException
414 * \brief Print the exception message
415 */
416class ModelException: public std::exception {
417public:
418 /*!
419 * \brief Constructor
420 * \param[in] class_name
421 * \param[in] function_name
422 * \param[in] msg
423 */
424 ModelException(const string& class_name, const string& function_name, const string& msg);
425
426 /*!
427 * \brief Construct error information (string version)
428 * \return error information
429 */
430 string ToString();
431
432 /*!
433 * \brief Overload function to construct error information
434 * \return \a char* error information
435 */
436 const char* what() const NOEXCEPT OVERRIDE;
437
438private:
439 std::runtime_error runtime_error_;
440};
441
442/*!
443 * \brief Check if the IP address is valid.
444 * \param[in] ip \a char* IP address.
445 */
446bool IsIpAddress(const char* ip);
447
448/*!
449 * \brief Writes an entry to the log file. Normally only used for debug
450 * \param[in] msg \a string log message
451 * \param[in] logpath \a string Optional
452 */
453void Log(const string& msg, const string& logpath = "debugInfo.log");
454
455/*!
456 * \brief Detect the available threads number
457 *
458 * Reference:
459 * - 1. http://stackoverflow.com/questions/150355/programmatically-find-the-number-of-cores-on-a-machine
460 * - 2. https://cmake.org/pipermail/cmake/2007-October/017286.html
461 */
463
464/*!
465 * \brief Set the default omp thread number if necessary
466 */
468
469/*!
470 * \brief Set the omp thread number by given thread number
471 * \param[in] n Thread number greater than 1.
472 */
473void SetOpenMPThread(int n);
474
475/*!
476 * \brief Print status messages for Debug
477 * \param[in] msg \a char* Message
478 */
479void StatusMessage(const char* msg);
480
481/*!
482 * \brief Print status messages for Debug
483 * \param[in] msg \a char* Message
484 */
485void StatusMessage(const string& msg);
486
487/*!
488 * \brief Sleep milliseconds
489 * \param[in] millisecs Sleep timespan.
490 */
491inline void SleepMs(const int millisecs) {
492#ifdef WINDOWS
493 Sleep(millisecs);
494#else
495 usleep(millisecs * 1000); // usleep takes sleep time_funcs in us (1 millionth of a second)
496#endif
497}
498
499} /* namespace ccgl */
500#endif /* CCGL_BASIC_H */
#define NOEXCEPT
A compatible reference to noexcept or throw() if not supported by the compiler.
Definition: basic.h:153
#define OVERRIDE
A compatible reference to override or blank if not supported by the compiler.
Definition: basic.h:160
Base type of all interfaces.
Definition: basic.h:407
Print the exception message.
Definition: basic.h:416
string ToString()
Construct error information (string version)
const char * what() const NOEXCEPT OVERRIDE
Overload function to construct error information.
ModelException(const string &class_name, const string &function_name, const string &msg)
Constructor.
Base class for classes that cannot be copied.
Definition: basic.h:385
Base of all classes.
Definition: basic.h:398
Common Cross-platform Geographic Library (CCGL)
void Log(const string &msg, const string &logpath="debugInfo.log")
Writes an entry to the log file.
int GetAvailableThreadNum()
Detect the available threads number.
std::map< string, string > STRING_MAP
Map of string key and string value.
Definition: basic.h:349
void SetDefaultOpenMPThread()
Set the default omp thread number if necessary.
vint64_t pos_t
Signed integer representing position.
Definition: basic.h:237
bool IsIpAddress(const char *ip)
Check if the IP address is valid.
void StatusMessage(const char *msg)
Print status messages for Debug.
std::map< string, double > STRDBL_MAP
Map of string key and double value.
Definition: basic.h:352
void SleepMs(const int millisecs)
Sleep milliseconds.
Definition: basic.h:491
void SetOpenMPThread(int n)
Set the omp thread number by given thread number.