Add streaming API
[folly.git] / folly / Portability.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <string.h>
20
21 #include <cstddef>
22
23 #include <folly/portability/Config.h>
24
25 #include <folly/CPortability.h>
26
27 // Unaligned loads and stores
28 namespace folly {
29 #if FOLLY_HAVE_UNALIGNED_ACCESS
30 constexpr bool kHasUnalignedAccess = true;
31 #else
32 constexpr bool kHasUnalignedAccess = false;
33 #endif
34 }
35
36 // compiler specific attribute translation
37 // msvc should come first, so if clang is in msvc mode it gets the right defines
38
39 #if defined(__clang__) || defined(__GNUC__)
40 # define FOLLY_ALIGNED(size) __attribute__((__aligned__(size)))
41 #elif defined(_MSC_VER)
42 # define FOLLY_ALIGNED(size) __declspec(align(size))
43 #else
44 # error Cannot define FOLLY_ALIGNED on this platform
45 #endif
46 #define FOLLY_ALIGNED_MAX FOLLY_ALIGNED(alignof(std::max_align_t))
47
48 // NOTE: this will only do checking in msvc with versions that support /analyze
49 #if _MSC_VER
50 # ifdef _USE_ATTRIBUTES_FOR_SAL
51 #    undef _USE_ATTRIBUTES_FOR_SAL
52 # endif
53 /* nolint */
54 # define _USE_ATTRIBUTES_FOR_SAL 1
55 # include <sal.h>
56 # define FOLLY_PRINTF_FORMAT _Printf_format_string_
57 # define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/
58 #else
59 # define FOLLY_PRINTF_FORMAT /**/
60 # define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) \
61   __attribute__((__format__(__printf__, format_param, dots_param)))
62 #endif
63
64 // deprecated
65 #if defined(__clang__) || defined(__GNUC__)
66 # define FOLLY_DEPRECATED(msg) __attribute__((__deprecated__(msg)))
67 #elif defined(_MSC_VER)
68 # define FOLLY_DEPRECATED(msg) __declspec(deprecated(msg))
69 #else
70 # define FOLLY_DEPRECATED(msg)
71 #endif
72
73 // warn unused result
74 #if defined(__has_cpp_attribute)
75 #if __has_cpp_attribute(nodiscard)
76 #define FOLLY_NODISCARD [[nodiscard]]
77 #endif
78 #endif
79 #if !defined FOLLY_NODISCARD
80 #if defined(_MSC_VER) && (_MSC_VER >= 1700)
81 #define FOLLY_NODISCARD _Check_return_
82 #elif defined(__clang__) || defined(__GNUC__)
83 #define FOLLY_NODISCARD __attribute__((__warn_unused_result__))
84 #else
85 #define FOLLY_NODISCARD
86 #endif
87 #endif
88 #define FOLLY_WARN_UNUSED_RESULT FOLLY_NODISCARD
89
90 // target
91 #ifdef _MSC_VER
92 # define FOLLY_TARGET_ATTRIBUTE(target)
93 #else
94 # define FOLLY_TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
95 #endif
96
97 // detection for 64 bit
98 #if defined(__x86_64__) || defined(_M_X64)
99 # define FOLLY_X64 1
100 #else
101 # define FOLLY_X64 0
102 #endif
103
104 #if defined(__aarch64__)
105 # define FOLLY_A64 1
106 #else
107 # define FOLLY_A64 0
108 #endif
109
110 #if defined (__powerpc64__)
111 # define FOLLY_PPC64 1
112 #else
113 # define FOLLY_PPC64 0
114 #endif
115
116 namespace folly {
117 constexpr bool kIsArchAmd64 = FOLLY_X64 == 1;
118 constexpr bool kIsArchAArch64 = FOLLY_A64 == 1;
119 constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1;
120 }
121
122 namespace folly {
123
124 #if FOLLY_SANITIZE_ADDRESS
125 constexpr bool kIsSanitizeAddress = true;
126 #else
127 constexpr bool kIsSanitizeAddress = false;
128 #endif
129
130 #if FOLLY_SANITIZE_THREAD
131 constexpr bool kIsSanitizeThread = true;
132 #else
133 constexpr bool kIsSanitizeThread = false;
134 #endif
135 }
136
137 // packing is very ugly in msvc
138 #ifdef _MSC_VER
139 # define FOLLY_PACK_ATTR /**/
140 # define FOLLY_PACK_PUSH __pragma(pack(push, 1))
141 # define FOLLY_PACK_POP __pragma(pack(pop))
142 #elif defined(__clang__) || defined(__GNUC__)
143 # define FOLLY_PACK_ATTR __attribute__((__packed__))
144 # define FOLLY_PACK_PUSH /**/
145 # define FOLLY_PACK_POP /**/
146 #else
147 # define FOLLY_PACK_ATTR /**/
148 # define FOLLY_PACK_PUSH /**/
149 # define FOLLY_PACK_POP /**/
150 #endif
151
152 // Generalize warning push/pop.
153 #if defined(_MSC_VER)
154 # define FOLLY_PUSH_WARNING __pragma(warning(push))
155 # define FOLLY_POP_WARNING __pragma(warning(pop))
156 // Disable the GCC warnings.
157 # define FOLLY_GCC_DISABLE_WARNING(warningName)
158 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber) __pragma(warning(disable: warningNumber))
159 #elif defined(__clang__) || defined(__GNUC__)
160 # define FOLLY_PUSH_WARNING _Pragma("GCC diagnostic push")
161 # define FOLLY_POP_WARNING _Pragma("GCC diagnostic pop")
162 # define FOLLY_GCC_DISABLE_WARNING_INTERNAL2(warningName) #warningName
163 # define FOLLY_GCC_DISABLE_WARNING(warningName) \
164   _Pragma(                                      \
165   FOLLY_GCC_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName))
166 // Disable the MSVC warnings.
167 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
168 #else
169 # define FOLLY_PUSH_WARNING
170 # define FOLLY_POP_WARNING
171 # define FOLLY_GCC_DISABLE_WARNING(warningName)
172 # define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
173 #endif
174
175 #ifdef HAVE_SHADOW_LOCAL_WARNINGS
176 #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS        \
177   FOLLY_GCC_DISABLE_WARNING("-Wshadow-compatible-local") \
178   FOLLY_GCC_DISABLE_WARNING("-Wshadow-local")
179 #else
180 #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS /* empty */
181 #endif
182
183 #if defined(__GNUC__) && !defined(__APPLE__) && !__GNUC_PREREQ(4,9)
184 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56019
185 // gcc 4.8.x incorrectly placed max_align_t in the root namespace
186 // Alias it into std (where it's found in 4.9 and later)
187 namespace std { typedef ::max_align_t max_align_t; }
188 #endif
189
190 // portable version check for clang
191 #ifndef __CLANG_PREREQ
192 # if defined __clang__ && defined __clang_major__ && defined __clang_minor__
193 /* nolint */
194 #  define __CLANG_PREREQ(maj, min) \
195     ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
196 # else
197 /* nolint */
198 #  define __CLANG_PREREQ(maj, min) 0
199 # endif
200 #endif
201
202 /* Platform specific TLS support
203  * gcc implements __thread
204  * msvc implements __declspec(thread)
205  * the semantics are the same
206  * (but remember __thread has different semantics when using emutls (ex. apple))
207  */
208 #if defined(_MSC_VER)
209 # define FOLLY_TLS __declspec(thread)
210 #elif defined(__GNUC__) || defined(__clang__)
211 # define FOLLY_TLS __thread
212 #else
213 # error cannot define platform specific thread local storage
214 #endif
215
216 #if FOLLY_MOBILE
217 #undef FOLLY_TLS
218 #endif
219
220 // It turns out that GNU libstdc++ and LLVM libc++ differ on how they implement
221 // the 'std' namespace; the latter uses inline namespaces. Wrap this decision
222 // up in a macro to make forward-declarations easier.
223 #if FOLLY_USE_LIBCPP
224 #include <__config>
225 #define FOLLY_NAMESPACE_STD_BEGIN     _LIBCPP_BEGIN_NAMESPACE_STD
226 #define FOLLY_NAMESPACE_STD_END       _LIBCPP_END_NAMESPACE_STD
227 #else
228 #define FOLLY_NAMESPACE_STD_BEGIN     namespace std {
229 #define FOLLY_NAMESPACE_STD_END       }
230 #endif
231
232 // If the new c++ ABI is used, __cxx11 inline namespace needs to be added to
233 // some types, e.g. std::list.
234 #if _GLIBCXX_USE_CXX11_ABI
235 #define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN \
236   inline _GLIBCXX_BEGIN_NAMESPACE_CXX11
237 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_END   _GLIBCXX_END_NAMESPACE_CXX11
238 #else
239 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN
240 # define FOLLY_GLIBCXX_NAMESPACE_CXX11_END
241 #endif
242
243 // MSVC specific defines
244 // mainly for posix compat
245 #ifdef _MSC_VER
246 #include <folly/portability/SysTypes.h>
247
248 // compiler specific to compiler specific
249 // nolint
250 # define __PRETTY_FUNCTION__ __FUNCSIG__
251
252 // Hide a GCC specific thing that breaks MSVC if left alone.
253 # define __extension__
254
255 // We have compiler support for the newest of the new, but
256 // MSVC doesn't tell us that.
257 #define __SSE4_2__ 1
258
259 #endif
260
261 // Debug
262 namespace folly {
263 #ifdef NDEBUG
264 constexpr auto kIsDebug = false;
265 #else
266 constexpr auto kIsDebug = true;
267 #endif
268 }
269
270 // Endianness
271 namespace folly {
272 #ifdef _MSC_VER
273 // It's MSVC, so we just have to guess ... and allow an override
274 #ifdef FOLLY_ENDIAN_BE
275 constexpr auto kIsLittleEndian = false;
276 #else
277 constexpr auto kIsLittleEndian = true;
278 #endif
279 #else
280 constexpr auto kIsLittleEndian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
281 #endif
282 constexpr auto kIsBigEndian = !kIsLittleEndian;
283 }
284
285 #ifndef FOLLY_SSE
286 # if defined(__SSE4_2__)
287 #  define FOLLY_SSE 4
288 #  define FOLLY_SSE_MINOR 2
289 # elif defined(__SSE4_1__)
290 #  define FOLLY_SSE 4
291 #  define FOLLY_SSE_MINOR 1
292 # elif defined(__SSE4__)
293 #  define FOLLY_SSE 4
294 #  define FOLLY_SSE_MINOR 0
295 # elif defined(__SSE3__)
296 #  define FOLLY_SSE 3
297 #  define FOLLY_SSE_MINOR 0
298 # elif defined(__SSE2__)
299 #  define FOLLY_SSE 2
300 #  define FOLLY_SSE_MINOR 0
301 # elif defined(__SSE__)
302 #  define FOLLY_SSE 1
303 #  define FOLLY_SSE_MINOR 0
304 # else
305 #  define FOLLY_SSE 0
306 #  define FOLLY_SSE_MINOR 0
307 # endif
308 #endif
309
310 #define FOLLY_SSE_PREREQ(major, minor) \
311   (FOLLY_SSE > major || FOLLY_SSE == major && FOLLY_SSE_MINOR >= minor)
312
313 #if FOLLY_UNUSUAL_GFLAGS_NAMESPACE
314 namespace FOLLY_GFLAGS_NAMESPACE { }
315 namespace gflags {
316 using namespace FOLLY_GFLAGS_NAMESPACE;
317 }  // namespace gflags
318 #endif
319
320 // for TARGET_OS_IPHONE
321 #ifdef __APPLE__
322 #include <TargetConditionals.h>
323 #endif
324
325 // RTTI may not be enabled for this compilation unit.
326 #if defined(__GXX_RTTI) || defined(__cpp_rtti) || \
327     (defined(_MSC_VER) && defined(_CPPRTTI))
328 # define FOLLY_HAS_RTTI 1
329 #endif
330
331 #if defined(__APPLE__) || defined(_MSC_VER)
332 #define FOLLY_STATIC_CTOR_PRIORITY_MAX
333 #else
334 // 101 is the highest priority allowed by the init_priority attribute.
335 // This priority is already used by JEMalloc and other memory allocators so
336 // we will take the next one.
337 #define FOLLY_STATIC_CTOR_PRIORITY_MAX __attribute__((__init_priority__(102)))
338 #endif
339
340 namespace folly {
341
342 #if __OBJC__
343 constexpr auto kIsObjC = true;
344 #else
345 constexpr auto kIsObjC = false;
346 #endif
347
348 #if defined(__linux__) && !FOLLY_MOBILE
349 constexpr auto kIsLinux = true;
350 #else
351 constexpr auto kIsLinux = false;
352 #endif
353
354 #if defined(_WIN32)
355 constexpr auto kIsWindows = true;
356 #else
357 constexpr auto kIsWindows = false;
358 #endif
359 }