123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- /*
- * Copyright 2011-present Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #pragma once
- #include <cstddef>
- #include <folly/portability/Config.h>
- #include <folly/CPortability.h>
- // Unaligned loads and stores
- namespace folly {
- #if FOLLY_HAVE_UNALIGNED_ACCESS
- constexpr bool kHasUnalignedAccess = true;
- #else
- constexpr bool kHasUnalignedAccess = false;
- #endif
- } // namespace folly
- // compiler specific attribute translation
- // msvc should come first, so if clang is in msvc mode it gets the right defines
- // NOTE: this will only do checking in msvc with versions that support /analyze
- #if _MSC_VER
- #ifdef _USE_ATTRIBUTES_FOR_SAL
- #undef _USE_ATTRIBUTES_FOR_SAL
- #endif
- /* nolint */
- #define _USE_ATTRIBUTES_FOR_SAL 1
- #include <sal.h> // @manual
- #define FOLLY_PRINTF_FORMAT _Printf_format_string_
- #define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/
- #else
- #define FOLLY_PRINTF_FORMAT /**/
- #define FOLLY_PRINTF_FORMAT_ATTR(format_param, dots_param) \
- __attribute__((__format__(__printf__, format_param, dots_param)))
- #endif
- // warn unused result
- #if defined(__has_cpp_attribute)
- #if __has_cpp_attribute(nodiscard)
- #define FOLLY_NODISCARD [[nodiscard]]
- #endif
- #endif
- #if !defined FOLLY_NODISCARD
- #if defined(_MSC_VER) && (_MSC_VER >= 1700)
- #define FOLLY_NODISCARD _Check_return_
- #elif defined(__clang__) || defined(__GNUC__)
- #define FOLLY_NODISCARD __attribute__((__warn_unused_result__))
- #else
- #define FOLLY_NODISCARD
- #endif
- #endif
- // target
- #ifdef _MSC_VER
- #define FOLLY_TARGET_ATTRIBUTE(target)
- #else
- #define FOLLY_TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
- #endif
- // detection for 64 bit
- #if defined(__x86_64__) || defined(_M_X64)
- #define FOLLY_X64 1
- #else
- #define FOLLY_X64 0
- #endif
- #if defined(__arm__)
- #define FOLLY_ARM 1
- #else
- #define FOLLY_ARM 0
- #endif
- #if defined(__aarch64__)
- #define FOLLY_AARCH64 1
- #else
- #define FOLLY_AARCH64 0
- #endif
- #if defined(__powerpc64__)
- #define FOLLY_PPC64 1
- #else
- #define FOLLY_PPC64 0
- #endif
- namespace folly {
- constexpr bool kIsArchArm = FOLLY_ARM == 1;
- constexpr bool kIsArchAmd64 = FOLLY_X64 == 1;
- constexpr bool kIsArchAArch64 = FOLLY_AARCH64 == 1;
- constexpr bool kIsArchPPC64 = FOLLY_PPC64 == 1;
- } // namespace folly
- namespace folly {
- /**
- * folly::kIsSanitizeAddress reports if folly was compiled with ASAN
- * enabled. Note that for compilation units outside of folly that include
- * folly/Portability.h, the value of kIsSanitizeAddress may be different
- * from whether or not the current compilation unit is being compiled with ASAN.
- */
- #if FOLLY_ASAN_ENABLED
- constexpr bool kIsSanitizeAddress = true;
- #else
- constexpr bool kIsSanitizeAddress = false;
- #endif
- #if FOLLY_SANITIZE_THREAD
- constexpr bool kIsSanitizeThread = true;
- #else
- constexpr bool kIsSanitizeThread = false;
- #endif
- #if FOLLY_SANITIZE
- constexpr bool kIsSanitize = true;
- #else
- constexpr bool kIsSanitize = false;
- #endif
- } // namespace folly
- // packing is very ugly in msvc
- #ifdef _MSC_VER
- #define FOLLY_PACK_ATTR /**/
- #define FOLLY_PACK_PUSH __pragma(pack(push, 1))
- #define FOLLY_PACK_POP __pragma(pack(pop))
- #elif defined(__clang__) || defined(__GNUC__)
- #define FOLLY_PACK_ATTR __attribute__((__packed__))
- #define FOLLY_PACK_PUSH /**/
- #define FOLLY_PACK_POP /**/
- #else
- #define FOLLY_PACK_ATTR /**/
- #define FOLLY_PACK_PUSH /**/
- #define FOLLY_PACK_POP /**/
- #endif
- // Generalize warning push/pop.
- #if defined(_MSC_VER)
- #define FOLLY_PUSH_WARNING __pragma(warning(push))
- #define FOLLY_POP_WARNING __pragma(warning(pop))
- // Disable the GCC warnings.
- #define FOLLY_GNU_DISABLE_WARNING(warningName)
- #define FOLLY_GCC_DISABLE_WARNING(warningName)
- #define FOLLY_CLANG_DISABLE_WARNING(warningName)
- #define FOLLY_MSVC_DISABLE_WARNING(warningNumber) \
- __pragma(warning(disable : warningNumber))
- #elif defined(__GNUC__)
- // Clang & GCC
- #define FOLLY_PUSH_WARNING _Pragma("GCC diagnostic push")
- #define FOLLY_POP_WARNING _Pragma("GCC diagnostic pop")
- #define FOLLY_GNU_DISABLE_WARNING_INTERNAL2(warningName) #warningName
- #define FOLLY_GNU_DISABLE_WARNING(warningName) \
- _Pragma( \
- FOLLY_GNU_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName))
- #ifdef __clang__
- #define FOLLY_CLANG_DISABLE_WARNING(warningName) \
- FOLLY_GNU_DISABLE_WARNING(warningName)
- #define FOLLY_GCC_DISABLE_WARNING(warningName)
- #else
- #define FOLLY_CLANG_DISABLE_WARNING(warningName)
- #define FOLLY_GCC_DISABLE_WARNING(warningName) \
- FOLLY_GNU_DISABLE_WARNING(warningName)
- #endif
- #define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
- #else
- #define FOLLY_PUSH_WARNING
- #define FOLLY_POP_WARNING
- #define FOLLY_GNU_DISABLE_WARNING(warningName)
- #define FOLLY_GCC_DISABLE_WARNING(warningName)
- #define FOLLY_CLANG_DISABLE_WARNING(warningName)
- #define FOLLY_MSVC_DISABLE_WARNING(warningNumber)
- #endif
- #ifdef FOLLY_HAVE_SHADOW_LOCAL_WARNINGS
- #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS \
- FOLLY_GNU_DISABLE_WARNING("-Wshadow-compatible-local") \
- FOLLY_GNU_DISABLE_WARNING("-Wshadow-local") \
- FOLLY_GNU_DISABLE_WARNING("-Wshadow")
- #else
- #define FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS /* empty */
- #endif
- // Globally disable -Wshadow for gcc < 5.
- #if __GNUC__ == 4 && !__clang__
- FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS
- #endif
- /* Platform specific TLS support
- * gcc implements __thread
- * msvc implements __declspec(thread)
- * the semantics are the same
- * (but remember __thread has different semantics when using emutls (ex. apple))
- */
- #if defined(_MSC_VER)
- #define FOLLY_TLS __declspec(thread)
- #elif defined(__GNUC__) || defined(__clang__)
- #define FOLLY_TLS __thread
- #else
- #error cannot define platform specific thread local storage
- #endif
- #if FOLLY_MOBILE
- #undef FOLLY_TLS
- #endif
- // It turns out that GNU libstdc++ and LLVM libc++ differ on how they implement
- // the 'std' namespace; the latter uses inline namespaces. Wrap this decision
- // up in a macro to make forward-declarations easier.
- #if FOLLY_USE_LIBCPP
- #include <__config> // @manual
- #define FOLLY_NAMESPACE_STD_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD
- #define FOLLY_NAMESPACE_STD_END _LIBCPP_END_NAMESPACE_STD
- #else
- #define FOLLY_NAMESPACE_STD_BEGIN namespace std {
- #define FOLLY_NAMESPACE_STD_END }
- #endif
- // If the new c++ ABI is used, __cxx11 inline namespace needs to be added to
- // some types, e.g. std::list.
- #if _GLIBCXX_USE_CXX11_ABI
- #define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN \
- inline _GLIBCXX_BEGIN_NAMESPACE_CXX11
- #define FOLLY_GLIBCXX_NAMESPACE_CXX11_END _GLIBCXX_END_NAMESPACE_CXX11
- #else
- #define FOLLY_GLIBCXX_NAMESPACE_CXX11_BEGIN
- #define FOLLY_GLIBCXX_NAMESPACE_CXX11_END
- #endif
- // MSVC specific defines
- // mainly for posix compat
- #ifdef _MSC_VER
- #include <folly/portability/SysTypes.h>
- // compiler specific to compiler specific
- // nolint
- #define __PRETTY_FUNCTION__ __FUNCSIG__
- // Hide a GCC specific thing that breaks MSVC if left alone.
- #define __extension__
- // We have compiler support for the newest of the new, but
- // MSVC doesn't tell us that.
- #define __SSE4_2__ 1
- #endif
- // Debug
- namespace folly {
- #ifdef NDEBUG
- constexpr auto kIsDebug = false;
- #else
- constexpr auto kIsDebug = true;
- #endif
- } // namespace folly
- // Endianness
- namespace folly {
- #ifdef _MSC_VER
- // It's MSVC, so we just have to guess ... and allow an override
- #ifdef FOLLY_ENDIAN_BE
- constexpr auto kIsLittleEndian = false;
- #else
- constexpr auto kIsLittleEndian = true;
- #endif
- #else
- constexpr auto kIsLittleEndian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
- #endif
- constexpr auto kIsBigEndian = !kIsLittleEndian;
- } // namespace folly
- #ifndef FOLLY_SSE
- #if defined(__SSE4_2__)
- #define FOLLY_SSE 4
- #define FOLLY_SSE_MINOR 2
- #elif defined(__SSE4_1__)
- #define FOLLY_SSE 4
- #define FOLLY_SSE_MINOR 1
- #elif defined(__SSE4__)
- #define FOLLY_SSE 4
- #define FOLLY_SSE_MINOR 0
- #elif defined(__SSE3__)
- #define FOLLY_SSE 3
- #define FOLLY_SSE_MINOR 0
- #elif defined(__SSE2__)
- #define FOLLY_SSE 2
- #define FOLLY_SSE_MINOR 0
- #elif defined(__SSE__)
- #define FOLLY_SSE 1
- #define FOLLY_SSE_MINOR 0
- #else
- #define FOLLY_SSE 0
- #define FOLLY_SSE_MINOR 0
- #endif
- #endif
- #define FOLLY_SSE_PREREQ(major, minor) \
- (FOLLY_SSE > major || FOLLY_SSE == major && FOLLY_SSE_MINOR >= minor)
- #ifndef FOLLY_NEON
- #if defined(__ARM_NEON) || defined(__ARM_NEON__)
- #define FOLLY_NEON 1
- #endif
- #endif
- #if FOLLY_UNUSUAL_GFLAGS_NAMESPACE
- namespace FOLLY_GFLAGS_NAMESPACE {}
- namespace gflags {
- using namespace FOLLY_GFLAGS_NAMESPACE;
- } // namespace gflags
- #endif
- // for TARGET_OS_IPHONE
- #ifdef __APPLE__
- #include <TargetConditionals.h> // @manual
- #endif
- // RTTI may not be enabled for this compilation unit.
- #if defined(__GXX_RTTI) || defined(__cpp_rtti) || \
- (defined(_MSC_VER) && defined(_CPPRTTI))
- #define FOLLY_HAS_RTTI 1
- #endif
- #if defined(__APPLE__) || defined(_MSC_VER)
- #define FOLLY_STATIC_CTOR_PRIORITY_MAX
- #else
- // 101 is the highest priority allowed by the init_priority attribute.
- // This priority is already used by JEMalloc and other memory allocators so
- // we will take the next one.
- #define FOLLY_STATIC_CTOR_PRIORITY_MAX __attribute__((__init_priority__(102)))
- #endif
- namespace folly {
- #if __OBJC__
- constexpr auto kIsObjC = true;
- #else
- constexpr auto kIsObjC = false;
- #endif
- #if FOLLY_MOBILE
- constexpr auto kIsMobile = true;
- #else
- constexpr auto kIsMobile = false;
- #endif
- #if defined(__linux__) && !FOLLY_MOBILE
- constexpr auto kIsLinux = true;
- #else
- constexpr auto kIsLinux = false;
- #endif
- #if defined(_WIN32)
- constexpr auto kIsWindows = true;
- #else
- constexpr auto kIsWindows = false;
- #endif
- #if __GLIBCXX__
- constexpr auto kIsGlibcxx = true;
- #else
- constexpr auto kIsGlibcxx = false;
- #endif
- #if _LIBCPP_VERSION
- constexpr auto kIsLibcpp = true;
- #else
- constexpr auto kIsLibcpp = false;
- #endif
- #if FOLLY_USE_LIBSTDCPP
- constexpr auto kIsLibstdcpp = true;
- #else
- constexpr auto kIsLibstdcpp = false;
- #endif
- #if _MSC_VER
- constexpr auto kMscVer = _MSC_VER;
- #else
- constexpr auto kMscVer = 0;
- #endif
- #if FOLLY_MICROSOFT_ABI_VER
- constexpr auto kMicrosoftAbiVer = FOLLY_MICROSOFT_ABI_VER;
- #else
- constexpr auto kMicrosoftAbiVer = 0;
- #endif
- // cpplib is an implementation of the standard library, and is the one typically
- // used with the msvc compiler
- #if _CPPLIB_VER
- constexpr auto kCpplibVer = _CPPLIB_VER;
- #else
- constexpr auto kCpplibVer = 0;
- #endif
- } // namespace folly
- // Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14
- // constexpr support is "good enough".
- #ifndef FOLLY_USE_CPP14_CONSTEXPR
- #if defined(__clang__)
- #define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L
- #elif defined(__GNUC__)
- #define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L
- #else
- #define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC?
- #endif
- #endif
- #if FOLLY_USE_CPP14_CONSTEXPR
- #define FOLLY_CPP14_CONSTEXPR constexpr
- #else
- #define FOLLY_CPP14_CONSTEXPR inline
- #endif
- // MSVC does not permit:
- //
- // extern int const num;
- // constexpr int const num = 3;
- //
- // Instead:
- //
- // extern int const num;
- // FOLLY_STORAGE_CONSTEXPR int const num = 3;
- //
- // True for MSVC 2015 and MSVC 2017.
- #if _MSC_VER
- #define FOLLY_STORAGE_CONSTEXPR
- #define FOLLY_STORAGE_CPP14_CONSTEXPR
- #else
- #if __ICC
- #define FOLLY_STORAGE_CONSTEXPR
- #else
- #define FOLLY_STORAGE_CONSTEXPR constexpr
- #endif
- #if FOLLY_USE_CPP14_CONSTEXPR
- #define FOLLY_STORAGE_CPP14_CONSTEXPR constexpr
- #else
- #define FOLLY_STORAGE_CPP14_CONSTEXPR
- #endif
- #endif
- #if __cpp_coroutines >= 201703L && __has_include(<experimental/coroutine>)
- #define FOLLY_HAS_COROUTINES 1
- #elif _MSC_VER && _RESUMABLE_FUNCTIONS_SUPPORTED
- #define FOLLY_HAS_COROUTINES 1
- #endif
- // MSVC 2017.5 && C++17
- #if __cpp_noexcept_function_type >= 201510 || \
- (_MSC_FULL_VER >= 191225816 && _MSVC_LANG > 201402)
- #define FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE 1
- #endif
- // Define FOLLY_HAS_EXCEPTIONS
- #if __cpp_exceptions >= 199711 || FOLLY_HAS_FEATURE(cxx_exceptions)
- #define FOLLY_HAS_EXCEPTIONS 1
- #elif __GNUC__
- #if __EXCEPTIONS
- #define FOLLY_HAS_EXCEPTIONS 1
- #else // __EXCEPTIONS
- #define FOLLY_HAS_EXCEPTIONS 0
- #endif // __EXCEPTIONS
- #elif FOLLY_MICROSOFT_ABI_VER
- #if _CPPUNWIND
- #define FOLLY_HAS_EXCEPTIONS 1
- #else // _CPPUNWIND
- #define FOLLY_HAS_EXCEPTIONS 0
- #endif // _CPPUNWIND
- #else
- #define FOLLY_HAS_EXCEPTIONS 1 // default assumption for unknown platforms
- #endif
- // feature test __cpp_lib_string_view is defined in <string>, which is
- // too heavy to include here. MSVC __has_include support arrived later
- // than string_view, so we need an alternate case for it.
- #ifdef __has_include
- #if __has_include(<string_view>) && __cplusplus >= 201703L
- #define FOLLY_HAS_STRING_VIEW 1
- #else
- #define FOLLY_HAS_STRING_VIEW 0
- #endif
- #else // __has_include
- #if _MSC_VER >= 1910 && (_MSVC_LANG > 201402 || __cplusplus > 201402)
- #define FOLLY_HAS_STRING_VIEW 1
- #else
- #define FOLLY_HAS_STRING_VIEW 0
- #endif
- #endif // __has_include
|