RavEngine
Loading...
Searching...
No Matches
phmap_config.h
1#if !defined(phmap_config_h_guard_)
2#define phmap_config_h_guard_
3
4// ---------------------------------------------------------------------------
5// Copyright (c) 2019, Gregory Popovitch - greg7mdp@gmail.com
6//
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License at
10//
11// https://www.apache.org/licenses/LICENSE-2.0
12//
13// Unless required by applicable law or agreed to in writing, software
14// distributed under the License is distributed on an "AS IS" BASIS,
15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16// See the License for the specific language governing permissions and
17// limitations under the License.
18//
19// Includes work from abseil-cpp (https://github.com/abseil/abseil-cpp)
20// with modifications.
21//
22// Copyright 2018 The Abseil Authors.
23//
24// Licensed under the Apache License, Version 2.0 (the "License");
25// you may not use this file except in compliance with the License.
26// You may obtain a copy of the License at
27//
28// https://www.apache.org/licenses/LICENSE-2.0
29//
30// Unless required by applicable law or agreed to in writing, software
31// distributed under the License is distributed on an "AS IS" BASIS,
32// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33// See the License for the specific language governing permissions and
34// limitations under the License.
35// ---------------------------------------------------------------------------
36
37#define PHMAP_VERSION_MAJOR 1
38#define PHMAP_VERSION_MINOR 0
39#define PHMAP_VERSION_PATCH 0
40
41// Included for the __GLIBC__ macro (or similar macros on other systems).
42#include <limits.h>
43
44#ifdef __cplusplus
45 // Included for __GLIBCXX__, _LIBCPP_VERSION
46 #include <cstddef>
47#endif // __cplusplus
48
49#if defined(__APPLE__)
50 // Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED,
51 // __IPHONE_8_0.
52 #include <Availability.h>
53 #include <TargetConditionals.h>
54#endif
55
56#define PHMAP_XSTR(x) PHMAP_STR(x)
57#define PHMAP_STR(x) #x
58#define PHMAP_VAR_NAME_VALUE(var) #var "=" PHMAP_STR(var)
59
60// -----------------------------------------------------------------------------
61// Some sanity checks
62// -----------------------------------------------------------------------------
63//#if defined(__CYGWIN__)
64// #error "Cygwin is not supported."
65//#endif
66
67#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__)
68 #error "phmap requires Visual Studio 2015 Update 2 or higher."
69#endif
70
71// We support gcc 4.7 and later.
72#if defined(__GNUC__) && !defined(__clang__)
73 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
74 #error "phmap requires gcc 4.7 or higher."
75 #endif
76#endif
77
78// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later.
79// This corresponds to Apple Xcode version 4.5.
80#if defined(__apple_build_version__) && __apple_build_version__ < 4211165
81 #error "phmap requires __apple_build_version__ of 4211165 or higher."
82#endif
83
84// Enforce C++11 as the minimum.
85#if defined(__cplusplus) && !defined(_MSC_VER)
86 #if __cplusplus < 201103L
87 #error "C++ versions less than C++11 are not supported."
88 #endif
89#endif
90
91// We have chosen glibc 2.12 as the minimum
92#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
93 #if !__GLIBC_PREREQ(2, 12)
94 #error "Minimum required version of glibc is 2.12."
95 #endif
96#endif
97
98#if defined(_STLPORT_VERSION)
99 #error "STLPort is not supported."
100#endif
101
102#if CHAR_BIT != 8
103 #error "phmap assumes CHAR_BIT == 8."
104#endif
105
106// phmap currently assumes that an int is 4 bytes.
107#if INT_MAX < 2147483647
108 #error "phmap assumes that int is at least 4 bytes. "
109#endif
110
111
112
113// -----------------------------------------------------------------------------
114// Compiler Feature Checks
115// -----------------------------------------------------------------------------
116
117#ifdef __has_builtin
118 #define PHMAP_HAVE_BUILTIN(x) __has_builtin(x)
119#else
120 #define PHMAP_HAVE_BUILTIN(x) 0
121#endif
122
123#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703) || __cplusplus >= 201703
124 #define PHMAP_HAVE_CC17 1
125#else
126 #define PHMAP_HAVE_CC17 0
127#endif
128
129#define PHMAP_BRANCHLESS 1
130
131// ----------------------------------------------------------------
132// Checks whether `std::is_trivially_destructible<T>` is supported.
133// ----------------------------------------------------------------
134#ifdef PHMAP_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
135 #error PHMAP_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set
136#elif defined(_LIBCPP_VERSION) || \
137 (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \
138 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
139 defined(_MSC_VER)
140 #define PHMAP_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
141#endif
142
143// --------------------------------------------------------------
144// Checks whether `std::is_trivially_default_constructible<T>` is
145// supported.
146// --------------------------------------------------------------
147#if defined(PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE)
148 #error PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
149#elif defined(PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE)
150 #error PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set
151#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \
152 (!defined(__clang__) && defined(__GNUC__) && \
153 (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \
154 (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \
155 (defined(_MSC_VER) && !defined(__NVCC__))
156 #define PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
157 #define PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
158#endif
159
160// -------------------------------------------------------------------
161// Checks whether C++11's `thread_local` storage duration specifier is
162// supported.
163// -------------------------------------------------------------------
164#ifdef PHMAP_HAVE_THREAD_LOCAL
165 #error PHMAP_HAVE_THREAD_LOCAL cannot be directly set
166#elif defined(__APPLE__)
167 #if __has_feature(cxx_thread_local) && \
168 !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
169 #define PHMAP_HAVE_THREAD_LOCAL 1
170 #endif
171#else // !defined(__APPLE__)
172 #define PHMAP_HAVE_THREAD_LOCAL 1
173#endif
174
175#if defined(__ANDROID__) && defined(__clang__)
176
177 #if __has_include(<android/ndk-version.h>)
178 #include <android/ndk-version.h>
179 #endif // __has_include(<android/ndk-version.h>)
180
181 #if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \
182 defined(__NDK_MINOR__) && \
183 ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))
184 #undef PHMAP_HAVE_TLS
185 #undef PHMAP_HAVE_THREAD_LOCAL
186 #endif
187#endif
188
189// ------------------------------------------------------------
190// Checks whether the __int128 compiler extension for a 128-bit
191// integral type is supported.
192// ------------------------------------------------------------
193#ifdef PHMAP_HAVE_INTRINSIC_INT128
194 #error PHMAP_HAVE_INTRINSIC_INT128 cannot be directly set
195#elif defined(__SIZEOF_INT128__)
196 #if (defined(__clang__) && !defined(_WIN32) && !defined(__aarch64__)) || \
197 (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \
198 (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__))
199 #define PHMAP_HAVE_INTRINSIC_INT128 1
200 #elif defined(__CUDACC__)
201 #if __CUDACC_VER__ >= 70000
202 #define PHMAP_HAVE_INTRINSIC_INT128 1
203 #endif // __CUDACC_VER__ >= 70000
204 #endif // defined(__CUDACC__)
205#endif
206
207// ------------------------------------------------------------------
208// Checks whether the compiler both supports and enables exceptions.
209// ------------------------------------------------------------------
210#ifdef PHMAP_HAVE_EXCEPTIONS
211 #error PHMAP_HAVE_EXCEPTIONS cannot be directly set.
212#elif defined(__clang__)
213 #if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
214 #define PHMAP_HAVE_EXCEPTIONS 1
215 #endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions)
216#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \
217 !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \
218 !(defined(_MSC_VER) && !defined(_CPPUNWIND))
219 #define PHMAP_HAVE_EXCEPTIONS 1
220#endif
221
222
223// -----------------------------------------------------------------------
224// Checks whether the platform has an mmap(2) implementation as defined in
225// POSIX.1-2001.
226// -----------------------------------------------------------------------
227#ifdef PHMAP_HAVE_MMAP
228 #error PHMAP_HAVE_MMAP cannot be directly set
229#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
230 defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \
231 defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \
232 defined(__ASYLO__)
233 #define PHMAP_HAVE_MMAP 1
234#endif
235
236// -----------------------------------------------------------------------
237// Checks the endianness of the platform.
238// -----------------------------------------------------------------------
239#if defined(PHMAP_IS_BIG_ENDIAN)
240 #error "PHMAP_IS_BIG_ENDIAN cannot be directly set."
241#endif
242
243#if defined(PHMAP_IS_LITTLE_ENDIAN)
244 #error "PHMAP_IS_LITTLE_ENDIAN cannot be directly set."
245#endif
246
247#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
248 __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
249 #define PHMAP_IS_LITTLE_ENDIAN 1
250#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
251 __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
252 #define PHMAP_IS_BIG_ENDIAN 1
253#elif defined(_WIN32)
254 #define PHMAP_IS_LITTLE_ENDIAN 1
255#else
256 #error "phmap endian detection needs to be set up for your compiler"
257#endif
258
259#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \
260 defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \
261 __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400
262 #define PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 1
263#else
264 #define PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 0
265#endif
266
267// ---------------------------------------------------------------------------
268// Checks whether C++17 std::any is available by checking whether <any> exists.
269// ---------------------------------------------------------------------------
270#ifdef PHMAP_HAVE_STD_ANY
271 #error "PHMAP_HAVE_STD_ANY cannot be directly set."
272#endif
273
274#ifdef __has_include
275 #if __has_include(<any>) && __cplusplus >= 201703L && \
276 !PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
277 #define PHMAP_HAVE_STD_ANY 1
278 #endif
279#endif
280
281#ifdef PHMAP_HAVE_STD_OPTIONAL
282 #error "PHMAP_HAVE_STD_OPTIONAL cannot be directly set."
283#endif
284
285#ifdef __has_include
286 #if __has_include(<optional>) && __cplusplus >= 201703L && \
287 !PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
288 #define PHMAP_HAVE_STD_OPTIONAL 1
289 #endif
290#endif
291
292#ifdef PHMAP_HAVE_STD_VARIANT
293 #error "PHMAP_HAVE_STD_VARIANT cannot be directly set."
294#endif
295
296#ifdef __has_include
297 #if __has_include(<variant>) && __cplusplus >= 201703L && \
298 !PHMAP_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE
299 #define PHMAP_HAVE_STD_VARIANT 1
300 #endif
301#endif
302
303#ifdef PHMAP_HAVE_STD_STRING_VIEW
304 #error "PHMAP_HAVE_STD_STRING_VIEW cannot be directly set."
305#endif
306
307#ifdef __has_include
308 #if __has_include(<string_view>) && __cplusplus >= 201703L && \
309 (!defined(_MSC_VER) || _MSC_VER >= 1920) // vs2019
310 #define PHMAP_HAVE_STD_STRING_VIEW 1
311 #endif
312#endif
313
314// #pragma message(PHMAP_VAR_NAME_VALUE(_MSVC_LANG))
315
316#if defined(_MSC_VER) && _MSC_VER >= 1910 && PHMAP_HAVE_CC17
317 // #define PHMAP_HAVE_STD_ANY 1
318 #define PHMAP_HAVE_STD_OPTIONAL 1
319 #define PHMAP_HAVE_STD_VARIANT 1
320 #if !defined(PHMAP_HAVE_STD_STRING_VIEW) && _MSC_VER >= 1920
321 #define PHMAP_HAVE_STD_STRING_VIEW 1
322 #endif
323#endif
324
325#if PHMAP_HAVE_CC17
326 #define PHMAP_HAVE_SHARED_MUTEX 1
327#endif
328
329#ifndef PHMAP_HAVE_STD_STRING_VIEW
330 #define PHMAP_HAVE_STD_STRING_VIEW 0
331#endif
332
333// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION
334// SEH exception from emplace for variant<SomeStruct> when constructing the
335// struct can throw. This defeats some of variant_test and
336// variant_exception_safety_test.
337#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG)
338 #define PHMAP_INTERNAL_MSVC_2017_DBG_MODE
339#endif
340
341
342// -----------------------------------------------------------------------------
343// Sanitizer Attributes
344// -----------------------------------------------------------------------------
345//
346// Sanitizer-related attributes are not "defined" in this file (and indeed
347// are not defined as such in any file). To utilize the following
348// sanitizer-related attributes within your builds, define the following macros
349// within your build using a `-D` flag, along with the given value for
350// `-fsanitize`:
351//
352// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8)
353// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only)
354// * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+)
355// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+)
356// * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only)
357// -----------------------------------------------------------------------------
358
359// -----------------------------------------------------------------------------
360// A function-like feature checking macro that is a wrapper around
361// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
362// nonzero constant integer if the attribute is supported or 0 if not.
363//
364// It evaluates to zero if `__has_attribute` is not defined by the compiler.
365// -----------------------------------------------------------------------------
366#ifdef __has_attribute
367 #define PHMAP_HAVE_ATTRIBUTE(x) __has_attribute(x)
368#else
369 #define PHMAP_HAVE_ATTRIBUTE(x) 0
370#endif
371
372// -----------------------------------------------------------------------------
373// A function-like feature checking macro that accepts C++11 style attributes.
374// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
375// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
376// find `__has_cpp_attribute`, will evaluate to 0.
377// -----------------------------------------------------------------------------
378#if defined(__cplusplus) && defined(__has_cpp_attribute)
379 #define PHMAP_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
380#else
381 #define PHMAP_HAVE_CPP_ATTRIBUTE(x) 0
382#endif
383
384// -----------------------------------------------------------------------------
385// Function Attributes
386// -----------------------------------------------------------------------------
387#if PHMAP_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__))
388 #define PHMAP_PRINTF_ATTRIBUTE(string_index, first_to_check) \
389 __attribute__((__format__(__printf__, string_index, first_to_check)))
390 #define PHMAP_SCANF_ATTRIBUTE(string_index, first_to_check) \
391 __attribute__((__format__(__scanf__, string_index, first_to_check)))
392#else
393 #define PHMAP_PRINTF_ATTRIBUTE(string_index, first_to_check)
394 #define PHMAP_SCANF_ATTRIBUTE(string_index, first_to_check)
395#endif
396
397#if PHMAP_HAVE_ATTRIBUTE(always_inline) || \
398 (defined(__GNUC__) && !defined(__clang__))
399 #define PHMAP_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
400 #define PHMAP_HAVE_ATTRIBUTE_ALWAYS_INLINE 1
401#else
402 #define PHMAP_ATTRIBUTE_ALWAYS_INLINE
403#endif
404
405#if !defined(__INTEL_COMPILER) && (PHMAP_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)))
406 #define PHMAP_ATTRIBUTE_NOINLINE __attribute__((noinline))
407 #define PHMAP_HAVE_ATTRIBUTE_NOINLINE 1
408#else
409 #define PHMAP_ATTRIBUTE_NOINLINE
410#endif
411
412#if PHMAP_HAVE_ATTRIBUTE(disable_tail_calls)
413 #define PHMAP_HAVE_ATTRIBUTE_NO_TAIL_CALL 1
414 #define PHMAP_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls))
415#elif defined(__GNUC__) && !defined(__clang__)
416 #define PHMAP_HAVE_ATTRIBUTE_NO_TAIL_CALL 1
417 #define PHMAP_ATTRIBUTE_NO_TAIL_CALL \
418 __attribute__((optimize("no-optimize-sibling-calls")))
419#else
420 #define PHMAP_ATTRIBUTE_NO_TAIL_CALL
421 #define PHMAP_HAVE_ATTRIBUTE_NO_TAIL_CALL 0
422#endif
423
424#if (PHMAP_HAVE_ATTRIBUTE(weak) || \
425 (defined(__GNUC__) && !defined(__clang__))) && \
426 !(defined(__llvm__) && defined(_WIN32))
427 #undef PHMAP_ATTRIBUTE_WEAK
428 #define PHMAP_ATTRIBUTE_WEAK __attribute__((weak))
429 #define PHMAP_HAVE_ATTRIBUTE_WEAK 1
430#else
431 #define PHMAP_ATTRIBUTE_WEAK
432 #define PHMAP_HAVE_ATTRIBUTE_WEAK 0
433#endif
434
435#if PHMAP_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__))
436 #define PHMAP_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index)))
437#else
438 #define PHMAP_ATTRIBUTE_NONNULL(...)
439#endif
440
441#if PHMAP_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__))
442 #define PHMAP_ATTRIBUTE_NORETURN __attribute__((noreturn))
443#elif defined(_MSC_VER)
444 #define PHMAP_ATTRIBUTE_NORETURN __declspec(noreturn)
445#else
446 #define PHMAP_ATTRIBUTE_NORETURN
447#endif
448
449#if defined(__GNUC__) && defined(ADDRESS_SANITIZER)
450 #define PHMAP_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
451#else
452 #define PHMAP_ATTRIBUTE_NO_SANITIZE_ADDRESS
453#endif
454
455#if defined(__GNUC__) && defined(MEMORY_SANITIZER)
456 #define PHMAP_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
457#else
458 #define PHMAP_ATTRIBUTE_NO_SANITIZE_MEMORY
459#endif
460
461#if defined(__GNUC__) && defined(THREAD_SANITIZER)
462 #define PHMAP_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
463#else
464 #define PHMAP_ATTRIBUTE_NO_SANITIZE_THREAD
465#endif
466
467#if defined(__GNUC__) && \
468 (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER))
469 #define PHMAP_ATTRIBUTE_NO_SANITIZE_UNDEFINED \
470 __attribute__((no_sanitize("undefined")))
471#else
472 #define PHMAP_ATTRIBUTE_NO_SANITIZE_UNDEFINED
473#endif
474
475#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY)
476 #define PHMAP_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi")))
477#else
478 #define PHMAP_ATTRIBUTE_NO_SANITIZE_CFI
479#endif
480
481#if defined(__GNUC__) && defined(SAFESTACK_SANITIZER)
482 #define PHMAP_ATTRIBUTE_NO_SANITIZE_SAFESTACK \
483 __attribute__((no_sanitize("safe-stack")))
484#else
485 #define PHMAP_ATTRIBUTE_NO_SANITIZE_SAFESTACK
486#endif
487
488#if PHMAP_HAVE_ATTRIBUTE(returns_nonnull) || \
489 (defined(__GNUC__) && \
490 (__GNUC__ > 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \
491 !defined(__clang__))
492 #define PHMAP_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
493#else
494 #define PHMAP_ATTRIBUTE_RETURNS_NONNULL
495#endif
496
497#ifdef PHMAP_HAVE_ATTRIBUTE_SECTION
498 #error PHMAP_HAVE_ATTRIBUTE_SECTION cannot be directly set
499#elif (PHMAP_HAVE_ATTRIBUTE(section) || \
500 (defined(__GNUC__) && !defined(__clang__))) && \
501 !defined(__APPLE__) && PHMAP_HAVE_ATTRIBUTE_WEAK
502 #define PHMAP_HAVE_ATTRIBUTE_SECTION 1
503 #ifndef PHMAP_ATTRIBUTE_SECTION
504 #define PHMAP_ATTRIBUTE_SECTION(name) \
505 __attribute__((section(#name))) __attribute__((noinline))
506 #endif
507 #ifndef PHMAP_ATTRIBUTE_SECTION_VARIABLE
508 #define PHMAP_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name)))
509 #endif
510 #ifndef PHMAP_DECLARE_ATTRIBUTE_SECTION_VARS
511 #define PHMAP_DECLARE_ATTRIBUTE_SECTION_VARS(name) \
512 extern char __start_##name[] PHMAP_ATTRIBUTE_WEAK; \
513 extern char __stop_##name[] PHMAP_ATTRIBUTE_WEAK
514 #endif
515 #ifndef PHMAP_DEFINE_ATTRIBUTE_SECTION_VARS
516 #define PHMAP_INIT_ATTRIBUTE_SECTION_VARS(name)
517 #define PHMAP_DEFINE_ATTRIBUTE_SECTION_VARS(name)
518 #endif
519 #define PHMAP_ATTRIBUTE_SECTION_START(name) \
520 (reinterpret_cast<void *>(__start_##name))
521 #define PHMAP_ATTRIBUTE_SECTION_STOP(name) \
522 (reinterpret_cast<void *>(__stop_##name))
523#else // !PHMAP_HAVE_ATTRIBUTE_SECTION
524 #define PHMAP_HAVE_ATTRIBUTE_SECTION 0
525 #define PHMAP_ATTRIBUTE_SECTION(name)
526 #define PHMAP_ATTRIBUTE_SECTION_VARIABLE(name)
527 #define PHMAP_INIT_ATTRIBUTE_SECTION_VARS(name)
528 #define PHMAP_DEFINE_ATTRIBUTE_SECTION_VARS(name)
529 #define PHMAP_DECLARE_ATTRIBUTE_SECTION_VARS(name)
530 #define PHMAP_ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void *>(0))
531 #define PHMAP_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void *>(0))
532#endif // PHMAP_ATTRIBUTE_SECTION
533
534#if PHMAP_HAVE_ATTRIBUTE(force_align_arg_pointer) || \
535 (defined(__GNUC__) && !defined(__clang__))
536 #if defined(__i386__)
537 #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \
538 __attribute__((force_align_arg_pointer))
539 #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
540 #elif defined(__x86_64__)
541 #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (1)
542 #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
543 #else // !__i386__ && !__x86_64
544 #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
545 #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
546 #endif // __i386__
547#else
548 #define PHMAP_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC
549 #define PHMAP_REQUIRE_STACK_ALIGN_TRAMPOLINE (0)
550#endif
551
552#if PHMAP_HAVE_ATTRIBUTE(nodiscard)
553 #define PHMAP_MUST_USE_RESULT [[nodiscard]]
554#elif defined(__clang__) && PHMAP_HAVE_ATTRIBUTE(warn_unused_result)
555 #define PHMAP_MUST_USE_RESULT __attribute__((warn_unused_result))
556#else
557 #define PHMAP_MUST_USE_RESULT
558#endif
559
560#if PHMAP_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__))
561 #define PHMAP_ATTRIBUTE_HOT __attribute__((hot))
562#else
563 #define PHMAP_ATTRIBUTE_HOT
564#endif
565
566#if PHMAP_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__))
567 #define PHMAP_ATTRIBUTE_COLD __attribute__((cold))
568#else
569 #define PHMAP_ATTRIBUTE_COLD
570#endif
571
572#if defined(__clang__)
573 #if PHMAP_HAVE_CPP_ATTRIBUTE(clang::reinitializes)
574 #define PHMAP_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]]
575 #else
576 #define PHMAP_ATTRIBUTE_REINITIALIZES
577 #endif
578#else
579 #define PHMAP_ATTRIBUTE_REINITIALIZES
580#endif
581
582#if PHMAP_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__))
583 #undef PHMAP_ATTRIBUTE_UNUSED
584 #define PHMAP_ATTRIBUTE_UNUSED __attribute__((__unused__))
585#else
586 #define PHMAP_ATTRIBUTE_UNUSED
587#endif
588
589#if PHMAP_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__))
590 #define PHMAP_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec")))
591#else
592 #define PHMAP_ATTRIBUTE_INITIAL_EXEC
593#endif
594
595#if PHMAP_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
596 #define PHMAP_ATTRIBUTE_PACKED __attribute__((__packed__))
597#else
598 #define PHMAP_ATTRIBUTE_PACKED
599#endif
600
601#if PHMAP_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__))
602 #define PHMAP_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes)))
603#else
604 #define PHMAP_ATTRIBUTE_FUNC_ALIGN(bytes)
605#endif
606
607// ----------------------------------------------------------------------
608// Figure out SSE support
609// ----------------------------------------------------------------------
610#ifndef PHMAP_HAVE_SSE2
611 #if defined(__SSE2__) || \
612 (defined(_MSC_VER) && \
613 (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2)))
614 #define PHMAP_HAVE_SSE2 1
615 #else
616 #define PHMAP_HAVE_SSE2 0
617 #endif
618#endif
619
620#ifndef PHMAP_HAVE_SSSE3
621 #if defined(__SSSE3__) || defined(__AVX2__)
622 #define PHMAP_HAVE_SSSE3 1
623 #else
624 #define PHMAP_HAVE_SSSE3 0
625 #endif
626#endif
627
628#if PHMAP_HAVE_SSSE3 && !PHMAP_HAVE_SSE2
629 #error "Bad configuration!"
630#endif
631
632#if PHMAP_HAVE_SSE2
633 #include <emmintrin.h>
634#endif
635
636#if PHMAP_HAVE_SSSE3
637 #include <tmmintrin.h>
638#endif
639
640
641// ----------------------------------------------------------------------
642// constexpr if
643// ----------------------------------------------------------------------
644#if PHMAP_HAVE_CC17
645 #define PHMAP_IF_CONSTEXPR(expr) if constexpr ((expr))
646#else
647 #define PHMAP_IF_CONSTEXPR(expr) if ((expr))
648#endif
649
650// ----------------------------------------------------------------------
651// base/macros.h
652// ----------------------------------------------------------------------
653
654// PHMAP_ARRAYSIZE()
655//
656// Returns the number of elements in an array as a compile-time constant, which
657// can be used in defining new arrays. If you use this macro on a pointer by
658// mistake, you will get a compile-time error.
659#define PHMAP_ARRAYSIZE(array) \
660 (sizeof(::phmap::macros_internal::ArraySizeHelper(array)))
661
662namespace phmap {
663namespace macros_internal {
664 // Note: this internal template function declaration is used by PHMAP_ARRAYSIZE.
665 // The function doesn't need a definition, as we only use its type.
666 template <typename T, size_t N>
667 auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
668} // namespace macros_internal
669} // namespace phmap
670
671// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported.
672#if defined(__clang__) && defined(__has_warning)
673 #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
674 #define PHMAP_FALLTHROUGH_INTENDED [[clang::fallthrough]]
675 #endif
676#elif defined(__GNUC__) && __GNUC__ >= 7
677 #define PHMAP_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
678#endif
679
680#ifndef PHMAP_FALLTHROUGH_INTENDED
681 #define PHMAP_FALLTHROUGH_INTENDED \
682 do { } while (0)
683#endif
684
685// PHMAP_DEPRECATED()
686//
687// Marks a deprecated class, struct, enum, function, method and variable
688// declarations. The macro argument is used as a custom diagnostic message (e.g.
689// suggestion of a better alternative).
690//
691// Example:
692//
693// class PHMAP_DEPRECATED("Use Bar instead") Foo {...};
694// PHMAP_DEPRECATED("Use Baz instead") void Bar() {...}
695//
696// Every usage of a deprecated entity will trigger a warning when compiled with
697// clang's `-Wdeprecated-declarations` option. This option is turned off by
698// default, but the warnings will be reported by clang-tidy.
699#if defined(__clang__) && __cplusplus >= 201103L
700 #define PHMAP_DEPRECATED(message) __attribute__((deprecated(message)))
701#endif
702
703#ifndef PHMAP_DEPRECATED
704 #define PHMAP_DEPRECATED(message)
705#endif
706
707// PHMAP_BAD_CALL_IF()
708//
709// Used on a function overload to trap bad calls: any call that matches the
710// overload will cause a compile-time error. This macro uses a clang-specific
711// "enable_if" attribute, as described at
712// http://clang.llvm.org/docs/AttributeReference.html#enable-if
713//
714// Overloads which use this macro should be bracketed by
715// `#ifdef PHMAP_BAD_CALL_IF`.
716//
717// Example:
718//
719// int isdigit(int c);
720// #ifdef PHMAP_BAD_CALL_IF
721// int isdigit(int c)
722// PHMAP_BAD_CALL_IF(c <= -1 || c > 255,
723// "'c' must have the value of an unsigned char or EOF");
724// #endif // PHMAP_BAD_CALL_IF
725
726#if defined(__clang__)
727 #if __has_attribute(enable_if)
728 #define PHMAP_BAD_CALL_IF(expr, msg) \
729 __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg)))
730 #endif
731#endif
732
733// PHMAP_ASSERT()
734//
735// In C++11, `assert` can't be used portably within constexpr functions.
736// PHMAP_ASSERT functions as a runtime assert but works in C++11 constexpr
737// functions. Example:
738//
739// constexpr double Divide(double a, double b) {
740// return PHMAP_ASSERT(b != 0), a / b;
741// }
742//
743// This macro is inspired by
744// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
745#if defined(NDEBUG)
746 #define PHMAP_ASSERT(expr) (false ? (void)(expr) : (void)0)
747#else
748 #define PHMAP_ASSERT(expr) \
749 (PHMAP_PREDICT_TRUE((expr)) ? (void)0 \
750 : [] { assert(false && #expr); }()) // NOLINT
751#endif
752
753#ifdef PHMAP_HAVE_EXCEPTIONS
754 #define PHMAP_INTERNAL_TRY try
755 #define PHMAP_INTERNAL_CATCH_ANY catch (...)
756 #define PHMAP_INTERNAL_RETHROW do { throw; } while (false)
757#else // PHMAP_HAVE_EXCEPTIONS
758 #define PHMAP_INTERNAL_TRY if (true)
759 #define PHMAP_INTERNAL_CATCH_ANY else if (false)
760 #define PHMAP_INTERNAL_RETHROW do {} while (false)
761#endif // PHMAP_HAVE_EXCEPTIONS
762
763
764#endif // phmap_config_h_guard_