IMP logo
IMP Reference Guide  2.14.0
The Integrative Modeling Platform
compiler_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/compiler_macros.h
3  * \brief Various compiler workarounds
4  *
5  * Copyright 2007-2020 IMP Inventors. All rights reserved.
6  */
7 
8 #ifndef IMPKERNEL_COMPILER_MACROS_H
9 #define IMPKERNEL_COMPILER_MACROS_H
10 
11 #include <boost/config.hpp>
12 #include <boost/version.hpp>
13 #if defined(BOOST_NO_CXX11_RANGE_BASED_FOR) || BOOST_VERSION < 105300
14 #include <boost/foreach.hpp>
15 #define IMP_FOREACH(v, r) BOOST_FOREACH(v, r)
16 #else
17 /** Use C++11 range-based for if available or BOOST_FOREACH if not. */
18 #define IMP_FOREACH(v, r) for (v : r)
19 #endif
20 
21 #define IMP_STRINGIFY(x) #x
22 
23 // recommended by http://gcc.gnu.org/gcc/Function-Names.html
24 #if defined(_MSC_VER)
25 #define IMP_CURRENT_FUNCTION __FUNCTION__
26 #define IMP_CURRENT_PRETTY_FUNCTION __FUNCTION__
27 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L
28 #define IMP_CURRENT_FUNCTION __FUNCTION__
29 #define IMP_CURRENT_PRETTY_FUNCTION __PRETTY_FUNCTION__
30 #else
31 #define IMP_CURRENT_FUNCTION __func__
32 #define IMP_CURRENT_PRETTY_FUNCTION __PRETTY_FUNCTION__
33 #endif
34 
35 #ifndef IMP_DOXYGEN
36 #ifdef __GNUC__
37 #define IMP_NO_SIDEEFFECTS __attribute__((pure))
38 #define IMP_UNUSED_FUNCTION __attribute__((unused))
39 #define IMP_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
40 #define IMP_RESTRICT __restrict__
41 
42 #else
43 #define IMP_NO_SIDEEFFECTS
44 #define IMP_UNUSED_FUNCTION
45 #define IMP_WARN_UNUSED_RESULT
46 #define IMP_RESTRICT
47 #endif
48 
49 #else
50 //! Use this to label a function with no side effects
51 /** \advancedmethod */
52 #define IMP_NO_SIDEEFFECTS
53 //! Use this to make the compiler (possibly) warn if the result is not used
54 /** \advancedmethod */
55 #define IMP_WARN_UNUSED_RESULT
56 //! Label a function that is never called
57 /** \advancedmethod */
58 #define IMP_UNUSED_FUNCTION
59 //! restrict means that a variable is not aliased with this function
60 #define IMP_RESTRICT
61 #endif
62 
63 #if defined(__clang__) && __clang_major__ >= 5
64 #define IMP_COMPILER_HAS_OVERRIDE 1
65 #elif !defined(__clang__) && defined(__GNUC__) && __cplusplus >= 201103L
66 // probably should be finer here
67 #define IMP_COMPILER_HAS_OVERRIDE 1
68 #else
69 #define IMP_COMPILER_HAS_OVERRIDE 0
70 #endif
71 
72 #ifdef IMP_DOXYGEN
73 //! Cause a compile error if this method does not override a parent method
74 /** This is helpful to catch accidental mismatches of call signatures between
75  the method and the parent method, which would cause the method to be
76  overloaded rather than overridden. Usually this macro should be used
77  whenever implementing a method that is declared virtual in the parent. */
78 #define IMP_OVERRIDE
79 #else
80 #if IMP_COMPILER_HAS_OVERRIDE
81 #define IMP_OVERRIDE override
82 #else
83 #define IMP_OVERRIDE
84 #endif
85 #endif
86 
87 #if defined(IMP_SWIG_WRAPPER)
88 #define IMP_COMPILER_HAS_FINAL 0
89 #elif defined(__clang__)
90 #define IMP_COMPILER_HAS_FINAL 1
91 #elif defined(__GNUC__) && __cplusplus >= 201103L
92 // probably should be finer here
93 #define IMP_COMPILER_HAS_FINAL 1
94 #else
95 #define IMP_COMPILER_HAS_FINAL 0
96 #endif
97 
98 #ifdef IMP_DOXYGEN
99 //! Have the compiler report an error if anything overrides this method
100 #define IMP_FINAL
101 #else
102 #if IMP_COMPILER_HAS_FINAL
103 #define IMP_FINAL final
104 #else
105 #define IMP_FINAL
106 #endif
107 #endif
108 
109 #if defined(__GNUC__) && __cplusplus >= 201103L
110 #define IMP_HAS_NOEXCEPT 1
111 #elif defined(__clang__) && defined(__has_feature)
112 #define IMP_HAS_NOEXCEPT __has_feature(cxx_noexcept)
113 #else
114 #define IMP_HAS_NOEXCEPT 0
115 #endif
116 
117 #if IMP_HAS_NOEXCEPT
118 #define IMP_NOEXCEPT noexcept
119 #define IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(Name) \
120  Name(const Name &) = default; \
121  Name &operator=(const Name &) = default
122 #else
123 // probably should be finer here
124 #define IMP_NOEXCEPT throw()
125 #define IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(Name)
126 #endif
127 
128 #if defined(__clang__) || defined(__GNUC__)
129 #define IMP_PRAGMA(x) _Pragma(IMP_STRINGIFY(x))
130 
131 #if defined(__clang__)
132 #define IMP_CLANG_PRAGMA(x) IMP_PRAGMA(clang x)
133 #define IMP_GCC_PRAGMA(x)
134 #define IMP_VC_PRAGMA(x)
135 #else
136 #define IMP_CLANG_PRAGMA(x)
137 #define IMP_GCC_PRAGMA(x) IMP_PRAGMA(GCC x)
138 #define IMP_VC_PRAGMA(x)
139 #endif
140 
141 #elif defined(_MSC_VER)
142 #define IMP_PRAGMA(x) __pragma(x)
143 #define IMP_CLANG_PRAGMA(x)
144 #define IMP_GCC_PRAGMA(x)
145 #define IMP_VC_PRAGMA(x) IMP_PRAGMA(x)
146 
147 #else
148 #define IMP_PRAGMA(x)
149 #define IMP_CLANG_PRAGMA(x)
150 #define IMP_GCC_PRAGMA(x)
151 #define IMP_VC_PRAGMA(x)
152 #endif
153 
154 #ifdef __clang__
155 
156 #define IMP_GCC_PUSH_POP(x)
157 
158 #define IMP_COMPILER_ENABLE_WARNINGS \
159  IMP_CLANG_PRAGMA(diagnostic push) \
160  IMP_CLANG_PRAGMA(diagnostic warning "-Wall") \
161  IMP_CLANG_PRAGMA(diagnostic warning "-Wextra") \
162  IMP_CLANG_PRAGMA(diagnostic warning "-Weverything") \
163  IMP_CLANG_PRAGMA(diagnostic ignored "-Wconversion") \
164  IMP_CLANG_PRAGMA(diagnostic ignored "-Wc++11-extensions") \
165  IMP_CLANG_PRAGMA(diagnostic ignored "-Wc++11-compat") \
166  IMP_CLANG_PRAGMA(diagnostic warning "-Wsign-compare") \
167  IMP_CLANG_PRAGMA(diagnostic ignored "-Wunused-member-function")
168 
169 #define IMP_HELPER_MACRO_PUSH_WARNINGS IMP_CLANG_PRAGMA(diagnostic push)
170 
171 #define IMP_HELPER_MACRO_POP_WARNINGS IMP_CLANG_PRAGMA(diagnostic pop)
172 
173 #define IMP_COMPILER_DISABLE_WARNINGS IMP_CLANG_PRAGMA(diagnostic pop)
174 
175 #elif defined(__GNUC__)
176 
177 /*ret+=["-Wno-deprecated",
178  "-Wstrict-aliasing=2",
179  -fno-operator-names",]*/
180 #if __GNUC__ > 4 || __GNUC_MINOR__ >= 6
181 #define IMP_GCC_PUSH_POP(x) IMP_PRAGMA(x)
182 #define IMP_GCC_CXX0X_COMPAT \
183  IMP_GCC_PRAGMA(diagnostic ignored \
184  "-Wc++0x-compat")
185 #ifdef IMP_SWIG_WRAPPER
186 #define IMP_GCC_PROTOTYPES
187 #else
188 #define IMP_GCC_PROTOTYPES \
189  IMP_GCC_PRAGMA(diagnostic warning "-Wmissing-declarations")
190 #endif
191 
192 #define IMP_HELPER_MACRO_PUSH_WARNINGS IMP_GCC_PRAGMA(diagnostic push)
193 
194 #define IMP_HELPER_MACRO_POP_WARNINGS IMP_GCC_PRAGMA(diagnostic pop)
195 
196 #else
197 #define IMP_GCC_PUSH_POP(x)
198 #define IMP_GCC_CXX0X_COMPAT
199 #define IMP_GCC_PROTOTYPES
200 #define IMP_HELPER_MACRO_PUSH_WARNINGS
201 #define IMP_HELPER_MACRO_POP_WARNINGS
202 #endif
203 
204 #define IMP_COMPILER_ENABLE_WARNINGS \
205  IMP_GCC_PUSH_POP(GCC diagnostic push) \
206  IMP_GCC_PRAGMA(diagnostic warning "-Wall") \
207  IMP_GCC_PRAGMA(diagnostic warning "-Wextra") \
208  IMP_GCC_PRAGMA(diagnostic warning "-Winit-self") \
209  IMP_GCC_PRAGMA(diagnostic warning "-Wcast-align") \
210  IMP_GCC_PRAGMA(diagnostic warning "-Woverloaded-virtual") \
211  IMP_GCC_PRAGMA(diagnostic warning "-Wdeprecated-declarations") \
212  IMP_GCC_PRAGMA(diagnostic warning \
213  "-Wundef") IMP_GCC_PROTOTYPES IMP_GCC_CXX0X_COMPAT
214 
215 #define IMP_COMPILER_DISABLE_WARNINGS IMP_GCC_PUSH_POP(GCC diagnostic pop)
216 
217 #elif defined(_MSC_VER)
218 #define IMP_GCC_PUSH_POP(x)
219 
220 #define IMP_COMPILER_ENABLE_WARNINGS \
221  IMP_VC_PRAGMA(warning(push)) IMP_VC_PRAGMA(warning(disable : 4273)) \
222  IMP_VC_PRAGMA(warning(disable : 4244)) \
223  IMP_VC_PRAGMA(warning(disable : 4068)) \
224  IMP_VC_PRAGMA(warning(disable : 4297))
225 
226 #define IMP_COMPILER_DISABLE_WARNINGS IMP_VC_PRAGMA(warning(pop))
227 
228 #define IMP_HELPER_MACRO_PUSH_WARNINGS
229 #define IMP_HELPER_MACRO_POP_WARNINGS
230 
231 #else
232 #define IMP_COMPILER_ENABLE_WARNINGS
233 #define IMP_COMPILER_DISABLE_WARNINGS
234 #define IMP_HELPER_MACRO_PUSH_WARNINGS
235 #define IMP_HELPER_MACRO_POP_WARNINGS
236 #endif
237 
238 #if defined(__GNUC__) || defined(__clang__)
239 #define IMP_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
240 #else
241 #define IMP_DEPRECATED_ATTRIBUTE
242 #endif
243 
244 // likely/unlikely macros provide manual optimization of branch
245 // prediction - particularly useful for rare cases in scoring
246 // functions, but use only if you know what you're doing cause
247 // profiler is better at this in 99.9% of times:
248 #if defined(__GNUC__)
249 #define IMP_LIKELY(x) __builtin_expect (!!(x), 1)
250 #define IMP_UNLIKELY(x) __builtin_expect (!!(x), 0)
251 #else // ifdef __GNUC__
252 #define IMP_LIKELY(x) x
253 #define IMP_UNLIKELY(x) x
254 #endif // ifdef __GNUC__
255 
256 #if defined(_MSC_VER)
257 //! platform independent C open() method
258 #define IMP_C_OPEN _open
259 #define IMP_C_CLOSE _close
260  //! platform independent C flag for open() method
261 #define IMP_C_OPEN_FLAG(x) _##x
262 #define IMP_C_OPEN_BINARY _O_BINARY
263 #else
264 //! platform independent C open() method
265 #define IMP_C_OPEN open
266 #define IMP_C_CLOSE close
267 //! platform independent C flag for open() method
268 #define IMP_C_OPEN_FLAG(x) x
269 #define IMP_C_OPEN_BINARY 0
270 #endif
271 
272 #endif /* IMPKERNEL_COMPILER_MACROS_H */