1 | /*! |
2 | * Copyright (c) 2015 by Contributors |
3 | * \file base.h |
4 | * \brief defines configuration macros |
5 | */ |
6 | #ifndef DMLC_BASE_H_ |
7 | #define DMLC_BASE_H_ |
8 | |
9 | /*! \brief whether use glog for logging */ |
10 | #ifndef DMLC_USE_GLOG |
11 | #define DMLC_USE_GLOG 0 |
12 | #endif |
13 | |
14 | /* |
15 | * The preprocessor definition DMLC_USE_LOGGING_LIBRARY determines whether to |
16 | * use a user-defined logging library. If defined, dmlc will not define the |
17 | * macros CHECK() and LOG() and instead locate CHECK() and LOG() from the value |
18 | * of DMLC_USE_LOGGING_LIBRARY. The DMLC_USE_LOGGING_LIBRARY macro shall be of |
19 | * form <my_logging.h>: |
20 | * |
21 | * #define DMLC_USE_LOGGING_LIBRARY <my_logging.h> |
22 | * |
23 | * Make sure to define CHECK() and LOG() macros in the provided header; |
24 | * otherwise the build will fail. |
25 | */ |
26 | |
27 | /*! |
28 | * \brief whether throw dmlc::Error instead of |
29 | * directly calling abort when FATAL error occured |
30 | * NOTE: this may still not be perfect. |
31 | * do not use FATAL and CHECK in destructors |
32 | */ |
33 | #ifndef DMLC_LOG_FATAL_THROW |
34 | #define DMLC_LOG_FATAL_THROW 1 |
35 | #endif |
36 | |
37 | /*! |
38 | * \brief whether always log a message before throw |
39 | * This can help identify the error that cannot be catched. |
40 | */ |
41 | #ifndef DMLC_LOG_BEFORE_THROW |
42 | #define DMLC_LOG_BEFORE_THROW 0 |
43 | #endif |
44 | |
45 | /*! |
46 | * \brief Whether to use customized logger, |
47 | * whose output can be decided by other libraries. |
48 | */ |
49 | #ifndef DMLC_LOG_CUSTOMIZE |
50 | #define DMLC_LOG_CUSTOMIZE 0 |
51 | #endif |
52 | |
53 | /*! |
54 | * \brief Whether to enable debug logging feature. |
55 | */ |
56 | #ifndef DMLC_LOG_DEBUG |
57 | #ifdef NDEBUG |
58 | #define DMLC_LOG_DEBUG 0 |
59 | #else |
60 | #define DMLC_LOG_DEBUG 1 |
61 | #endif |
62 | #endif |
63 | |
64 | /*! |
65 | * \brief Whether to disable date message on the log. |
66 | */ |
67 | #ifndef DMLC_LOG_NODATE |
68 | #define DMLC_LOG_NODATE 0 |
69 | #endif |
70 | |
71 | /*! \brief whether compile with hdfs support */ |
72 | #ifndef DMLC_USE_HDFS |
73 | #define DMLC_USE_HDFS 0 |
74 | #endif |
75 | |
76 | /*! \brief whether compile with s3 support */ |
77 | #ifndef DMLC_USE_S3 |
78 | #define DMLC_USE_S3 0 |
79 | #endif |
80 | |
81 | /*! \brief whether or not use parameter server */ |
82 | #ifndef DMLC_USE_PS |
83 | #define DMLC_USE_PS 0 |
84 | #endif |
85 | |
86 | /*! \brief whether or not use c++11 support */ |
87 | #ifndef DMLC_USE_CXX11 |
88 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(_MSC_VER) |
89 | #define DMLC_USE_CXX11 1 |
90 | #else |
91 | #define DMLC_USE_CXX11 (__cplusplus >= 201103L) |
92 | #endif |
93 | #endif |
94 | |
95 | /*! \brief strict CXX11 support */ |
96 | #ifndef DMLC_STRICT_CXX11 |
97 | #if defined(_MSC_VER) |
98 | #define DMLC_STRICT_CXX11 1 |
99 | #else |
100 | #define DMLC_STRICT_CXX11 (__cplusplus >= 201103L) |
101 | #endif |
102 | #endif |
103 | |
104 | /*! \brief Whether cxx11 thread local is supported */ |
105 | #ifndef DMLC_CXX11_THREAD_LOCAL |
106 | #if defined(_MSC_VER) |
107 | #define DMLC_CXX11_THREAD_LOCAL (_MSC_VER >= 1900) |
108 | #elif defined(__clang__) |
109 | #define DMLC_CXX11_THREAD_LOCAL (__has_feature(cxx_thread_local)) |
110 | #else |
111 | #define DMLC_CXX11_THREAD_LOCAL (__cplusplus >= 201103L) |
112 | #endif |
113 | #endif |
114 | |
115 | /*! \brief Whether to use modern thread local construct */ |
116 | #ifndef DMLC_MODERN_THREAD_LOCAL |
117 | #define DMLC_MODERN_THREAD_LOCAL 1 |
118 | #endif |
119 | |
120 | |
121 | |
122 | /*! \brief whether RTTI is enabled */ |
123 | #ifndef DMLC_ENABLE_RTTI |
124 | #define DMLC_ENABLE_RTTI 1 |
125 | #endif |
126 | |
127 | /*! \brief whether use fopen64 */ |
128 | #ifndef DMLC_USE_FOPEN64 |
129 | #define DMLC_USE_FOPEN64 1 |
130 | #endif |
131 | |
132 | /// check for C++11 support |
133 | #if DMLC_USE_CXX11 |
134 | #if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1900) |
135 | // MSVC doesn't support __cplusplus macro properly until MSVC 2017 |
136 | // We want to also support MSVC 2015, so manually check _MSC_VER |
137 | |
138 | #pragma message("Compiling without c++11, some features may be disabled") |
139 | #undef DMLC_USE_CXX11 |
140 | #define DMLC_USE_CXX11 0 |
141 | |
142 | #endif // (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1900) |
143 | #endif // DMLC_USE_CXX11 |
144 | |
145 | /*! |
146 | * \brief Use little endian for binary serialization |
147 | * if this is set to 0, use big endian. |
148 | */ |
149 | #ifndef DMLC_IO_USE_LITTLE_ENDIAN |
150 | #define DMLC_IO_USE_LITTLE_ENDIAN 1 |
151 | #endif |
152 | |
153 | /*! |
154 | * \brief Enable std::thread related modules, |
155 | * Used to disable some module in mingw compile. |
156 | */ |
157 | #ifndef DMLC_ENABLE_STD_THREAD |
158 | #define DMLC_ENABLE_STD_THREAD DMLC_USE_CXX11 |
159 | #endif |
160 | |
161 | /*! \brief whether enable regex support, actually need g++-4.9 or higher*/ |
162 | #ifndef DMLC_USE_REGEX |
163 | #define DMLC_USE_REGEX DMLC_STRICT_CXX11 |
164 | #endif |
165 | |
166 | /*! \brief helper macro to supress unused warning */ |
167 | #if defined(__GNUC__) |
168 | #define DMLC_ATTRIBUTE_UNUSED __attribute__((unused)) |
169 | #else |
170 | #define DMLC_ATTRIBUTE_UNUSED |
171 | #endif |
172 | |
173 | /*! \brief helper macro to supress Undefined Behavior Sanitizer for a specific function */ |
174 | #if defined(__clang__) |
175 | #define DMLC_SUPPRESS_UBSAN __attribute__((no_sanitize("undefined"))) |
176 | #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) |
177 | #define DMLC_SUPPRESS_UBSAN __attribute__((no_sanitize_undefined)) |
178 | #else |
179 | #define DMLC_SUPPRESS_UBSAN |
180 | #endif |
181 | |
182 | /*! \brief helper macro to generate string concat */ |
183 | #define DMLC_STR_CONCAT_(__x, __y) __x##__y |
184 | #define DMLC_STR_CONCAT(__x, __y) DMLC_STR_CONCAT_(__x, __y) |
185 | |
186 | /*! |
187 | * \brief Disable copy constructor and assignment operator. |
188 | * |
189 | * If C++11 is supported, both copy and move constructors and |
190 | * assignment operators are deleted explicitly. Otherwise, they are |
191 | * only declared but not implemented. Place this macro in private |
192 | * section if C++11 is not available. |
193 | */ |
194 | #ifndef DISALLOW_COPY_AND_ASSIGN |
195 | # if DMLC_USE_CXX11 |
196 | # define DISALLOW_COPY_AND_ASSIGN(T) \ |
197 | T(T const&) = delete; \ |
198 | T(T&&) = delete; \ |
199 | T& operator=(T const&) = delete; \ |
200 | T& operator=(T&&) = delete |
201 | # else |
202 | # define DISALLOW_COPY_AND_ASSIGN(T) \ |
203 | T(T const&); \ |
204 | T& operator=(T const&) |
205 | # endif |
206 | #endif |
207 | |
208 | #ifdef __APPLE__ |
209 | # define off64_t off_t |
210 | #endif |
211 | |
212 | #ifdef _MSC_VER |
213 | #if _MSC_VER < 1900 |
214 | // NOTE: sprintf_s is not equivalent to snprintf, |
215 | // they are equivalent when success, which is sufficient for our case |
216 | #define snprintf sprintf_s |
217 | #define vsnprintf vsprintf_s |
218 | #endif |
219 | #else |
220 | #ifdef _FILE_OFFSET_BITS |
221 | #if _FILE_OFFSET_BITS == 32 |
222 | #pragma message("Warning: FILE OFFSET BITS defined to be 32 bit") |
223 | #endif |
224 | #endif |
225 | |
226 | extern "C" { |
227 | #include <sys/types.h> |
228 | } |
229 | #endif |
230 | |
231 | #ifdef _MSC_VER |
232 | //! \cond Doxygen_Suppress |
233 | typedef signed char int8_t; |
234 | typedef __int16 int16_t; |
235 | typedef __int32 int32_t; |
236 | typedef __int64 int64_t; |
237 | typedef unsigned char uint8_t; |
238 | typedef unsigned __int16 uint16_t; |
239 | typedef unsigned __int32 uint32_t; |
240 | typedef unsigned __int64 uint64_t; |
241 | //! \endcond |
242 | #else |
243 | #include <inttypes.h> |
244 | #endif |
245 | #include <string> |
246 | #include <vector> |
247 | |
248 | #if defined(_MSC_VER) && _MSC_VER < 1900 |
249 | #define noexcept_true throw () |
250 | #define noexcept_false |
251 | #define noexcept(a) noexcept_##a |
252 | #endif |
253 | |
254 | #if defined(_MSC_VER) |
255 | #define DMLC_NO_INLINE __declspec(noinline) |
256 | #else |
257 | #define DMLC_NO_INLINE __attribute__((noinline)) |
258 | #endif |
259 | |
260 | #if defined(__GNUC__) || defined(__clang__) |
261 | #define DMLC_ALWAYS_INLINE inline __attribute__((__always_inline__)) |
262 | #elif defined(_MSC_VER) |
263 | #define DMLC_ALWAYS_INLINE __forceinline |
264 | #else |
265 | #define DMLC_ALWAYS_INLINE inline |
266 | #endif |
267 | |
268 | #if DMLC_USE_CXX11 |
269 | #define DMLC_THROW_EXCEPTION noexcept(false) |
270 | #define DMLC_NO_EXCEPTION noexcept(true) |
271 | #else |
272 | #define DMLC_THROW_EXCEPTION |
273 | #define DMLC_NO_EXCEPTION |
274 | #endif |
275 | |
276 | /*! \brief namespace for dmlc */ |
277 | namespace dmlc { |
278 | /*! |
279 | * \brief safely get the beginning address of a vector |
280 | * \param vec input vector |
281 | * \return beginning address of a vector |
282 | */ |
283 | template<typename T> |
284 | inline T *BeginPtr(std::vector<T> &vec) { // NOLINT(*) |
285 | if (vec.size() == 0) { |
286 | return NULL; |
287 | } else { |
288 | return &vec[0]; |
289 | } |
290 | } |
291 | /*! |
292 | * \brief get the beginning address of a const vector |
293 | * \param vec input vector |
294 | * \return beginning address of a vector |
295 | */ |
296 | template<typename T> |
297 | inline const T *BeginPtr(const std::vector<T> &vec) { |
298 | if (vec.size() == 0) { |
299 | return NULL; |
300 | } else { |
301 | return &vec[0]; |
302 | } |
303 | } |
304 | /*! |
305 | * \brief get the beginning address of a string |
306 | * \param str input string |
307 | * \return beginning address of a string |
308 | */ |
309 | inline char* BeginPtr(std::string &str) { // NOLINT(*) |
310 | if (str.length() == 0) return NULL; |
311 | return &str[0]; |
312 | } |
313 | /*! |
314 | * \brief get the beginning address of a const string |
315 | * \param str input string |
316 | * \return beginning address of a string |
317 | */ |
318 | inline const char* BeginPtr(const std::string &str) { |
319 | if (str.length() == 0) return NULL; |
320 | return &str[0]; |
321 | } |
322 | } // namespace dmlc |
323 | |
324 | #if defined(_MSC_VER) && _MSC_VER < 1900 |
325 | #define constexpr const |
326 | #define alignof __alignof |
327 | #endif |
328 | |
329 | /* If fopen64 is not defined by current machine, |
330 | replace fopen64 with std::fopen. Also determine ability to print stack trace |
331 | for fatal error and define DMLC_LOG_STACK_TRACE if stack trace can be |
332 | produced. Always keep this include directive at the bottom of dmlc/base.h */ |
333 | #ifdef DMLC_CORE_USE_CMAKE |
334 | #include <dmlc/build_config.h> |
335 | #else |
336 | #include <dmlc/build_config_default.h> |
337 | #endif |
338 | |
339 | #endif // DMLC_BASE_H_ |
340 | |