text: /*
   * 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(WIN64) || defined(_WIN64) || defined(_M_X64) || defined(_M_AMD64) \
   || defined(__amd64__) || defined(__x86_64__)
  # 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 {
  
  #if FOLLY_SANITIZE_ADDRESS
  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.
  #ifndef __SSE4_2__
  #define __SSE4_2__ 1
  #endif
  
  #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)
  #  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 _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
  #define FOLLY_STORAGE_CONSTEXPR constexpr
  #if FOLLY_USE_CPP14_CONSTEXPR
  #define FOLLY_STORAGE_CPP14_CONSTEXPR constexpr
  #else
  #define FOLLY_STORAGE_CPP14_CONSTEXPR
  #endif
  #endif
  
  #if __cpp_coroutines >= 201703L && FOLLY_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
  