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
226extern "C" {
227#include <sys/types.h>
228}
229#endif
230
231#ifdef _MSC_VER
232//! \cond Doxygen_Suppress
233typedef signed char int8_t;
234typedef __int16 int16_t;
235typedef __int32 int32_t;
236typedef __int64 int64_t;
237typedef unsigned char uint8_t;
238typedef unsigned __int16 uint16_t;
239typedef unsigned __int32 uint32_t;
240typedef 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 */
277namespace 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 */
283template<typename T>
284inline 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 */
296template<typename T>
297inline 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 */
309inline 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 */
318inline 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