Created
August 10, 2015 22:44
-
-
Save espositofulvio/eac2fb08acf2e430c516 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/CMakeLists.txt b/CMakeLists.txt | |
index be6fbbe..0c3e190 100644 | |
--- a/CMakeLists.txt | |
+++ b/CMakeLists.txt | |
@@ -1,293 +1,292 @@ | |
# See www/CMake.html for instructions on how to build libcxx with CMake. | |
#=============================================================================== | |
# Setup Project | |
#=============================================================================== | |
cmake_minimum_required(VERSION 2.8) | |
if(POLICY CMP0042) | |
cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default | |
endif() | |
if(POLICY CMP0022) | |
cmake_policy(SET CMP0022 NEW) # Required when interacting with LLVM and Clang | |
endif() | |
project(libcxx CXX C) | |
set(PACKAGE_NAME libcxx) | |
set(PACKAGE_VERSION trunk-svn) | |
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") | |
set(PACKAGE_BUGREPORT "[email protected]") | |
# Add path for custom modules | |
set(CMAKE_MODULE_PATH | |
"${CMAKE_CURRENT_SOURCE_DIR}/cmake" | |
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" | |
${CMAKE_MODULE_PATH} | |
) | |
# Require out of source build. | |
include(MacroEnsureOutOfSourceBuild) | |
MACRO_ENSURE_OUT_OF_SOURCE_BUILD( | |
"${PROJECT_NAME} requires an out of source build. Please create a separate | |
build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." | |
) | |
# Find the LLVM sources and simulate LLVM CMake options. | |
include(HandleOutOfTreeLLVM) | |
if (LIBCXX_BUILT_STANDALONE AND NOT LLVM_FOUND) | |
message(WARNING "UNSUPPORTED LIBCXX CONFIGURATION DETECTED: " | |
"llvm-config not found and LLVM_PATH not defined.\n" | |
"Reconfigure with -DLLVM_CONFIG=path/to/llvm-config " | |
"or -DLLVM_PATH=path/to/llvm-source-root.") | |
endif() | |
#=============================================================================== | |
# Setup CMake Options | |
#=============================================================================== | |
# Basic options --------------------------------------------------------------- | |
option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON) | |
option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) | |
option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS}) | |
set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING | |
"Define suffix of library directory name (32/64)") | |
option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON) | |
option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON) | |
# ABI Library options --------------------------------------------------------- | |
set(LIBCXX_CXX_ABI "${LIBCXX_CXX_ABI}" CACHE STRING | |
"Specify C++ ABI library to use." FORCE) | |
set(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++) | |
set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) | |
option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" OFF) | |
# Build libc++abi with libunwind. We need this option to determine whether to | |
# link with libunwind or libgcc_s while running the test cases. | |
option(LIBCXXABI_USE_LLVM_UNWINDER "Build and use the LLVM unwinder." OFF) | |
# Target options -------------------------------------------------------------- | |
option(LIBCXX_BUILD_32_BITS "Build 32 bit libc++." ${LLVM_BUILD_32_BITS}) | |
set(LIBCXX_SYSROOT "" CACHE STRING "Use alternate sysroot.") | |
set(LIBCXX_GCC_TOOLCHAIN "" CACHE STRING "Use alternate GCC toolchain.") | |
# Feature options ------------------------------------------------------------- | |
option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON) | |
option(LIBCXX_ENABLE_RTTI "Use run time type information." ON) | |
option(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE "Build libc++ with support for the global filesystem namespace." ON) | |
option(LIBCXX_ENABLE_STDIN "Build libc++ with support for stdin/std::cin." ON) | |
option(LIBCXX_ENABLE_STDOUT "Build libc++ with support for stdout/std::cout." ON) | |
option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON) | |
option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for thread-unsafe C functions" ON) | |
option(LIBCXX_ENABLE_MONOTONIC_CLOCK | |
"Build libc++ with support for a monotonic clock. | |
This option may only be used when LIBCXX_ENABLE_THREADS=OFF." ON) | |
# Misc options ---------------------------------------------------------------- | |
option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) | |
option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF) | |
option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF) | |
set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING | |
"The Profile-rt library used to build with code coverage") | |
#=============================================================================== | |
# Check option configurations | |
#=============================================================================== | |
# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON only when | |
# LIBCXX_ENABLE_THREADS is on. | |
if(LIBCXX_ENABLE_THREADS AND NOT LIBCXX_ENABLE_MONOTONIC_CLOCK) | |
message(FATAL_ERROR "LIBCXX_ENABLE_MONOTONIC_CLOCK can only be set to OFF" | |
" when LIBCXX_ENABLE_THREADS is also set to OFF.") | |
endif() | |
# Ensure LLVM_USE_SANITIZER is not specified when LIBCXX_GENERATE_COVERAGE | |
# is ON. | |
if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE) | |
message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE") | |
endif() | |
# Set LIBCXX_BUILD_32_BITS to (LIBCXX_BUILD_32_BITS OR LLVM_BUILD_32_BITS) | |
# and check that we can build with 32 bits if requested. | |
if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32) | |
if (LIBCXX_BUILD_32_BITS AND NOT LLVM_BUILD_32_BITS) # Don't duplicate the output from LLVM | |
message(STATUS "Building 32 bits executables and libraries.") | |
endif() | |
elseif(LIBCXX_BUILD_32_BITS) | |
message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.") | |
endif() | |
# Check that this option is not enabled on Apple and emit a usage warning. | |
if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY) | |
if (APPLE) | |
message(FATAL_ERROR "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is not supported on OS X") | |
else() | |
message(WARNING "LIBCXX_ENABLE_STATIC_ABI_LIBRARY is an experimental option") | |
endif() | |
endif() | |
#=============================================================================== | |
# Configure System | |
#=============================================================================== | |
set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER}) | |
set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) | |
set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) | |
set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) | |
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) | |
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) | |
# Declare libc++ configuration variables. | |
# They are intended for use as follows: | |
# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker. | |
# LIBCXX_COMPILE_FLAGS: Compile only flags. | |
# LIBCXX_LINK_FLAGS: Linker only flags. | |
set(LIBCXX_COMPILE_FLAGS "") | |
set(LIBCXX_LINK_FLAGS "") | |
set(LIBCXX_LIBRARIES "") | |
# Configure compiler. | |
include(config-ix) | |
# Configure coverage options. | |
if (LIBCXX_GENERATE_COVERAGE) | |
include(CodeCoverage) | |
set(CMAKE_BUILD_TYPE "COVERAGE" CACHE STRING "" FORCE) | |
endif() | |
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) | |
#=============================================================================== | |
# Setup Compiler Flags | |
#=============================================================================== | |
-include(HandleLibCXXABI) # Steup the ABI library flags | |
+include(HandleLibCXXABI) # Setup the ABI library flags | |
# Include macros for adding and removing libc++ flags. | |
include(HandleLibcxxFlags) | |
# Remove flags that may have snuck in. | |
remove_flags(-DNDEBUG -UNDEBUG -D_DEBUG | |
-stdlib=libc++ -stdlib=libstdc++ -lc++abi -m32) | |
# Required flags ============================================================== | |
add_compile_flags_if_supported(-std=c++11) | |
if (NOT MSVC AND NOT LIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG) | |
message(FATAL_ERROR "C++11 is required but the compiler does not support -std=c++11") | |
endif() | |
# On all systems the system c++ standard library headers need to be excluded. | |
# MSVC only has -X, which disables all default includes; including the crt. | |
# Thus, we do nothing and hope we don't accidentally include any of the C++ | |
# headers | |
add_compile_flags_if_supported(-nostdinc++) | |
# Target flags ================================================================ | |
add_flags_if(LIBCXX_BUILD_32_BITS -m32) | |
add_flags_if(LIBCXX_TARGET_TRIPLE "-target ${LIBCXX_TARGET_TRIPLE}") | |
add_flags_if(LIBCXX_SYSROOT "--sysroot ${LIBCXX_SYSROOT}") | |
add_flags_if(LIBCXX_GCC_TOOLCHAIN "-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}") | |
# Warning flags =============================================================== | |
add_definitions(-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
add_compile_flags_if_supported( | |
-Wall -W -Wwrite-strings | |
-Wno-unused-parameter -Wno-long-long | |
-Werror=return-type) | |
if (LIBCXX_ENABLE_WERROR) | |
add_compile_flags_if_supported(-Werror) | |
add_compile_flags_if_supported(-WX) | |
else() | |
# TODO(EricWF) Remove this. We shouldn't be suppressing errors when -Werror is | |
# added elsewhere. | |
add_compile_flags_if_supported(-Wno-error) | |
endif() | |
if (LIBCXX_ENABLE_PEDANTIC) | |
add_compile_flags_if_supported(-pedantic) | |
endif() | |
# Exception flags ============================================================= | |
if (LIBCXX_ENABLE_EXCEPTIONS) | |
# Catches C++ exceptions only and tells the compiler to assume that extern C | |
# functions never throw a C++ exception. | |
add_compile_flags_if_supported(-EHsc) | |
else() | |
add_definitions(-D_LIBCPP_NO_EXCEPTIONS) | |
add_compile_flags_if_supported(-EHs- -EHa-) | |
add_compile_flags_if_supported(-fno-exceptions) | |
endif() | |
# RTTI flags ================================================================== | |
if (NOT LIBCXX_ENABLE_RTTI) | |
add_definitions(-D_LIBCPP_NO_RTTI) | |
add_compile_flags_if_supported(-GR-) | |
add_compile_flags_if_supported(-fno-rtti) | |
endif() | |
# Assertion flags ============================================================= | |
define_if(LIBCXX_ENABLE_ASSERTIONS -UNDEBUG) | |
define_if_not(LIBCXX_ENABLE_ASSERTIONS -DNDEBUG) | |
if (LIBCXX_ENABLE_ASSERTIONS) | |
# MSVC doesn't like _DEBUG on release builds. See PR 4379. | |
define_if_not(MSVC -D_DEBUG) | |
endif() | |
# Feature flags =============================================================== | |
define_if(MSVC -D_CRT_SECURE_NO_WARNINGS) | |
define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE -D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE) | |
define_if_not(LIBCXX_ENABLE_STDIN -D_LIBCPP_HAS_NO_STDIN) | |
define_if_not(LIBCXX_ENABLE_STDOUT -D_LIBCPP_HAS_NO_STDOUT) | |
define_if_not(LIBCXX_ENABLE_THREADS -D_LIBCPP_HAS_NO_THREADS) | |
define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK -D_LIBCPP_HAS_NO_MONOTONIC_CLOCK) | |
define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS -D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) | |
- | |
# Sanitizer flags | |
# Configure for sanitizers. If LIBCXX_BUILT_STANDALONE then we have to do | |
# the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it. | |
if (LIBCXX_BUILT_STANDALONE) | |
set(LLVM_USE_SANITIZER "" CACHE STRING | |
"Define the sanitizer used to build the library and tests") | |
# NOTE: LLVM_USE_SANITIZER checks for a UNIX like system instead of MSVC. | |
# But we don't have LLVM_ON_UNIX so checking for MSVC is the best we can do. | |
if (LLVM_USE_SANITIZER AND NOT MSVC) | |
add_flags_if_supported("-fno-omit-frame-pointer") | |
add_flags_if_supported("-gline-tables-only") | |
if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND | |
NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO") | |
add_flags_if_supported("-gline-tables-only") | |
endif() | |
if (LLVM_USE_SANITIZER STREQUAL "Address") | |
add_flags("-fsanitize=address") | |
elseif (LLVM_USE_SANITIZER MATCHES "Memory(WithOrigins)?") | |
add_flags(-fsanitize=memory) | |
if (LLVM_USE_SANITIZER STREQUAL "MemoryWithOrigins") | |
add_flags("-fsanitize-memory-track-origins") | |
endif() | |
elseif (LLVM_USE_SANITIZER STREQUAL "Undefined") | |
add_flags("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all") | |
elseif (LLVM_USE_SANITIZER STREQUAL "Thread") | |
add_flags(-fsanitize=thread) | |
else() | |
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}") | |
endif() | |
elseif(LLVM_USE_SANITIZER AND MSVC) | |
message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.") | |
endif() | |
endif() | |
#=============================================================================== | |
# Setup Source Code And Tests | |
#=============================================================================== | |
include_directories(include) | |
add_subdirectory(include) | |
add_subdirectory(lib) | |
if (LIBCXX_INCLUDE_TESTS) | |
add_subdirectory(test) | |
endif() | |
diff --git a/include/__config b/include/__config | |
index 600f0fb..f24b1d9 100644 | |
--- a/include/__config | |
+++ b/include/__config | |
@@ -1,770 +1,777 @@ | |
// -*- C++ -*- | |
//===--------------------------- __config ---------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#ifndef _LIBCPP_CONFIG | |
#define _LIBCPP_CONFIG | |
#if !defined(_MSC_VER) || defined(__clang__) | |
#pragma GCC system_header | |
#endif | |
#ifdef __GNUC__ | |
#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) | |
#else | |
#define _GNUC_VER 0 | |
#endif | |
#define _LIBCPP_VERSION 3800 | |
#define _LIBCPP_ABI_VERSION 1 | |
#define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y | |
#define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) | |
#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) | |
#ifndef __has_attribute | |
#define __has_attribute(__x) 0 | |
#endif | |
#ifndef __has_builtin | |
#define __has_builtin(__x) 0 | |
#endif | |
#ifndef __has_feature | |
#define __has_feature(__x) 0 | |
#endif | |
// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by | |
// the compiler and '1' otherwise. | |
#ifndef __is_identifier | |
#define __is_identifier(__x) 1 | |
#endif | |
#ifdef __LITTLE_ENDIAN__ | |
#if __LITTLE_ENDIAN__ | |
#define _LIBCPP_LITTLE_ENDIAN 1 | |
#define _LIBCPP_BIG_ENDIAN 0 | |
#endif // __LITTLE_ENDIAN__ | |
#endif // __LITTLE_ENDIAN__ | |
#ifdef __BIG_ENDIAN__ | |
#if __BIG_ENDIAN__ | |
#define _LIBCPP_LITTLE_ENDIAN 0 | |
#define _LIBCPP_BIG_ENDIAN 1 | |
#endif // __BIG_ENDIAN__ | |
#endif // __BIG_ENDIAN__ | |
#ifdef __FreeBSD__ | |
# include <sys/endian.h> | |
# if _BYTE_ORDER == _LITTLE_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 1 | |
# define _LIBCPP_BIG_ENDIAN 0 | |
# else // _BYTE_ORDER == _LITTLE_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 0 | |
# define _LIBCPP_BIG_ENDIAN 1 | |
# endif // _BYTE_ORDER == _LITTLE_ENDIAN | |
# ifndef __LONG_LONG_SUPPORTED | |
# define _LIBCPP_HAS_NO_LONG_LONG | |
# endif // __LONG_LONG_SUPPORTED | |
#endif // __FreeBSD__ | |
#ifdef __NetBSD__ | |
# include <sys/endian.h> | |
# if _BYTE_ORDER == _LITTLE_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 1 | |
# define _LIBCPP_BIG_ENDIAN 0 | |
# else // _BYTE_ORDER == _LITTLE_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 0 | |
# define _LIBCPP_BIG_ENDIAN 1 | |
# endif // _BYTE_ORDER == _LITTLE_ENDIAN | |
# define _LIBCPP_HAS_QUICK_EXIT | |
#endif // __NetBSD__ | |
#ifdef _WIN32 | |
# define _LIBCPP_LITTLE_ENDIAN 1 | |
# define _LIBCPP_BIG_ENDIAN 0 | |
// Compiler intrinsics (MSVC) | |
#if defined(_MSC_VER) && _MSC_VER >= 1400 | |
# define _LIBCPP_HAS_IS_BASE_OF | |
# endif | |
# if defined(_MSC_VER) && !defined(__clang__) | |
# define _LIBCPP_MSVC // Using Microsoft Visual C++ compiler | |
# define _LIBCPP_TOSTRING2(x) #x | |
# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) | |
# define _LIBCPP_WARNING(x) __pragma(message(__FILE__ "(" _LIBCPP_TOSTRING(__LINE__) ") : warning note: " x)) | |
# endif | |
# // If mingw not explicitly detected, assume using MS C runtime only. | |
# ifndef __MINGW32__ | |
# define _LIBCPP_MSVCRT // Using Microsoft's C Runtime library | |
# endif | |
#endif // _WIN32 | |
#ifdef __sun__ | |
# include <sys/isa_defs.h> | |
# ifdef _LITTLE_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 1 | |
# define _LIBCPP_BIG_ENDIAN 0 | |
# else | |
# define _LIBCPP_LITTLE_ENDIAN 0 | |
# define _LIBCPP_BIG_ENDIAN 1 | |
# endif | |
#endif // __sun__ | |
#if defined(__CloudABI__) | |
// Certain architectures provide arc4random(). Prefer using | |
// arc4random() over /dev/{u,}random to make it possible to obtain | |
// random data even when using sandboxing mechanisms such as chroots, | |
// Capsicum, etc. | |
# define _LIBCPP_USING_ARC4_RANDOM | |
#elif defined(__native_client__) | |
// NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, | |
// including accesses to the special files under /dev. C++11's | |
// std::random_device is instead exposed through a NaCl syscall. | |
# define _LIBCPP_USING_NACL_RANDOM | |
#elif defined(_WIN32) | |
# define _LIBCPP_USING_WIN32_RANDOM | |
#else | |
# define _LIBCPP_USING_DEV_RANDOM | |
#endif | |
#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) | |
# include <endian.h> | |
# if __BYTE_ORDER == __LITTLE_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 1 | |
# define _LIBCPP_BIG_ENDIAN 0 | |
# elif __BYTE_ORDER == __BIG_ENDIAN | |
# define _LIBCPP_LITTLE_ENDIAN 0 | |
# define _LIBCPP_BIG_ENDIAN 1 | |
# else // __BYTE_ORDER == __BIG_ENDIAN | |
# error unable to determine endian | |
# endif | |
#endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) | |
#ifdef _WIN32 | |
// only really useful for a DLL | |
#ifdef _LIBCPP_DLL // this should be a compiler builtin define ideally... | |
# ifdef cxx_EXPORTS | |
# define _LIBCPP_HIDDEN | |
# define _LIBCPP_FUNC_VIS __declspec(dllexport) | |
# define _LIBCPP_TYPE_VIS __declspec(dllexport) | |
# else | |
# define _LIBCPP_HIDDEN | |
# define _LIBCPP_FUNC_VIS __declspec(dllimport) | |
# define _LIBCPP_TYPE_VIS __declspec(dllimport) | |
# endif | |
#else | |
# define _LIBCPP_HIDDEN | |
# define _LIBCPP_FUNC_VIS | |
# define _LIBCPP_TYPE_VIS | |
#endif | |
#define _LIBCPP_TYPE_VIS_ONLY | |
#define _LIBCPP_FUNC_VIS_ONLY | |
#ifndef _LIBCPP_INLINE_VISIBILITY | |
# ifdef _LIBCPP_MSVC | |
# define _LIBCPP_INLINE_VISIBILITY __forceinline | |
# else // MinGW GCC and Clang | |
# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) | |
# endif | |
#endif | |
#ifndef _LIBCPP_EXCEPTION_ABI | |
#define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS | |
#endif | |
#ifndef _LIBCPP_ALWAYS_INLINE | |
# ifdef _LIBCPP_MSVC | |
# define _LIBCPP_ALWAYS_INLINE __forceinline | |
# endif | |
#endif | |
#endif // _WIN32 | |
#ifndef _LIBCPP_HIDDEN | |
#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) | |
#endif | |
#ifndef _LIBCPP_FUNC_VIS | |
#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) | |
#endif | |
#ifndef _LIBCPP_TYPE_VIS | |
# if __has_attribute(__type_visibility__) | |
# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default"))) | |
# else | |
# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default"))) | |
# endif | |
#endif | |
#ifndef _LIBCPP_TYPE_VIS_ONLY | |
# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS | |
#endif | |
#ifndef _LIBCPP_FUNC_VIS_ONLY | |
# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS | |
#endif | |
#ifndef _LIBCPP_INLINE_VISIBILITY | |
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) | |
#endif | |
#ifndef _LIBCPP_EXCEPTION_ABI | |
#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) | |
#endif | |
#ifndef _LIBCPP_ALWAYS_INLINE | |
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__)) | |
#endif | |
#if defined(__clang__) | |
#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ | |
!defined(__arm__) | |
#define _LIBCPP_ALTERNATE_STRING_LAYOUT | |
#endif | |
#if __has_feature(cxx_alignas) | |
# define _ALIGNAS_TYPE(x) alignas(x) | |
# define _ALIGNAS(x) alignas(x) | |
#else | |
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) | |
# define _ALIGNAS(x) __attribute__((__aligned__(x))) | |
#endif | |
#if !__has_feature(cxx_alias_templates) | |
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES | |
#endif | |
#if __cplusplus < 201103L | |
typedef __char16_t char16_t; | |
typedef __char32_t char32_t; | |
#endif | |
#if !(__has_feature(cxx_exceptions)) | |
#define _LIBCPP_NO_EXCEPTIONS | |
#endif | |
#if !(__has_feature(cxx_rtti)) | |
#define _LIBCPP_NO_RTTI | |
#endif | |
#if !(__has_feature(cxx_strong_enums)) | |
#define _LIBCPP_HAS_NO_STRONG_ENUMS | |
#endif | |
#if !(__has_feature(cxx_decltype)) | |
#define _LIBCPP_HAS_NO_DECLTYPE | |
#endif | |
#if __has_feature(cxx_attributes) | |
# define _LIBCPP_NORETURN [[noreturn]] | |
#else | |
# define _LIBCPP_NORETURN __attribute__ ((noreturn)) | |
#endif | |
#define _LIBCPP_UNUSED __attribute__((__unused__)) | |
#if !(__has_feature(cxx_defaulted_functions)) | |
#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS | |
#endif // !(__has_feature(cxx_defaulted_functions)) | |
#if !(__has_feature(cxx_deleted_functions)) | |
#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS | |
#endif // !(__has_feature(cxx_deleted_functions)) | |
#if !(__has_feature(cxx_lambdas)) | |
#define _LIBCPP_HAS_NO_LAMBDAS | |
#endif | |
#if !(__has_feature(cxx_nullptr)) | |
#define _LIBCPP_HAS_NO_NULLPTR | |
#endif | |
#if !(__has_feature(cxx_rvalue_references)) | |
#define _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#endif | |
#if !(__has_feature(cxx_static_assert)) | |
#define _LIBCPP_HAS_NO_STATIC_ASSERT | |
#endif | |
#if !(__has_feature(cxx_auto_type)) | |
#define _LIBCPP_HAS_NO_AUTO_TYPE | |
#endif | |
#if !(__has_feature(cxx_access_control_sfinae)) || !__has_feature(cxx_trailing_return) | |
#define _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
#endif | |
#if !(__has_feature(cxx_variadic_templates)) | |
#define _LIBCPP_HAS_NO_VARIADICS | |
#endif | |
#if !(__has_feature(cxx_trailing_return)) | |
#define _LIBCPP_HAS_NO_TRAILING_RETURN | |
#endif | |
#if !(__has_feature(cxx_generalized_initializers)) | |
#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS | |
#endif | |
#if __has_feature(is_base_of) | |
# define _LIBCPP_HAS_IS_BASE_OF | |
#endif | |
#if __has_feature(is_final) | |
# define _LIBCPP_HAS_IS_FINAL | |
#endif | |
// Objective-C++ features (opt-in) | |
#if __has_feature(objc_arc) | |
#define _LIBCPP_HAS_OBJC_ARC | |
#endif | |
#if __has_feature(objc_arc_weak) | |
#define _LIBCPP_HAS_OBJC_ARC_WEAK | |
#define _LIBCPP_HAS_NO_STRONG_ENUMS | |
#endif | |
#if !(__has_feature(cxx_constexpr)) | |
#define _LIBCPP_HAS_NO_CONSTEXPR | |
#endif | |
#if !(__has_feature(cxx_relaxed_constexpr)) | |
#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR | |
#endif | |
#if !(__has_feature(cxx_variable_templates)) | |
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES | |
#endif | |
#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L | |
#if defined(__FreeBSD__) | |
#define _LIBCPP_HAS_QUICK_EXIT | |
#define _LIBCPP_HAS_C11_FEATURES | |
#elif defined(__ANDROID__) | |
#define _LIBCPP_HAS_QUICK_EXIT | |
#elif defined(__linux__) | |
#include <features.h> | |
#if __GLIBC_PREREQ(2, 15) | |
#define _LIBCPP_HAS_QUICK_EXIT | |
#endif | |
#if __GLIBC_PREREQ(2, 17) | |
#define _LIBCPP_HAS_C11_FEATURES | |
#endif | |
#endif | |
#endif | |
#if (__has_feature(cxx_noexcept)) | |
# define _NOEXCEPT noexcept | |
# define _NOEXCEPT_(x) noexcept(x) | |
# define _NOEXCEPT_OR_FALSE(x) noexcept(x) | |
#else | |
# define _NOEXCEPT throw() | |
# define _NOEXCEPT_(x) | |
# define _NOEXCEPT_OR_FALSE(x) false | |
#endif | |
#if __has_feature(underlying_type) | |
# define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) | |
#endif | |
#if __has_feature(is_literal) | |
# define _LIBCPP_IS_LITERAL(T) __is_literal(T) | |
#endif | |
// Inline namespaces are available in Clang regardless of C++ dialect. | |
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { | |
#define _LIBCPP_END_NAMESPACE_STD } } | |
#define _VSTD std::_LIBCPP_NAMESPACE | |
namespace std { | |
inline namespace _LIBCPP_NAMESPACE { | |
} | |
} | |
#if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer) | |
#define _LIBCPP_HAS_NO_ASAN | |
#endif | |
#elif defined(__GNUC__) | |
#define _ALIGNAS(x) __attribute__((__aligned__(x))) | |
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) | |
#define _LIBCPP_NORETURN __attribute__((noreturn)) | |
#define _LIBCPP_UNUSED __attribute__((__unused__)) | |
#if _GNUC_VER >= 407 | |
#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) | |
#define _LIBCPP_IS_LITERAL(T) __is_literal_type(T) | |
#define _LIBCPP_HAS_IS_FINAL | |
#endif | |
#if defined(__GNUC__) && _GNUC_VER >= 403 | |
# define _LIBCPP_HAS_IS_BASE_OF | |
#endif | |
#if !__EXCEPTIONS | |
#define _LIBCPP_NO_EXCEPTIONS | |
#endif | |
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES | |
// constexpr was added to GCC in 4.6. | |
#if _GNUC_VER < 406 | |
#define _LIBCPP_HAS_NO_CONSTEXPR | |
// Can only use constexpr in c++11 mode. | |
#elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L | |
#define _LIBCPP_HAS_NO_CONSTEXPR | |
#endif | |
// No version of GCC supports relaxed constexpr rules | |
#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR | |
// GCC 5 will support variable templates | |
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES | |
#define _NOEXCEPT throw() | |
#define _NOEXCEPT_(x) | |
#define _NOEXCEPT_OR_FALSE(x) false | |
#ifndef __GXX_EXPERIMENTAL_CXX0X__ | |
#define _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
#define _LIBCPP_HAS_NO_DECLTYPE | |
#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS | |
#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS | |
#define _LIBCPP_HAS_NO_NULLPTR | |
#define _LIBCPP_HAS_NO_STATIC_ASSERT | |
#define _LIBCPP_HAS_NO_UNICODE_CHARS | |
#define _LIBCPP_HAS_NO_VARIADICS | |
#define _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS | |
#define _LIBCPP_HAS_NO_STRONG_ENUMS | |
#else // __GXX_EXPERIMENTAL_CXX0X__ | |
#define _LIBCPP_HAS_NO_TRAILING_RETURN | |
#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS | |
#if _GNUC_VER < 403 | |
#define _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#endif | |
#if _GNUC_VER < 403 | |
#define _LIBCPP_HAS_NO_STATIC_ASSERT | |
#endif | |
#if _GNUC_VER < 404 | |
#define _LIBCPP_HAS_NO_DECLTYPE | |
#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS | |
#define _LIBCPP_HAS_NO_UNICODE_CHARS | |
#define _LIBCPP_HAS_NO_VARIADICS | |
#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS | |
#endif // _GNUC_VER < 404 | |
#if _GNUC_VER < 406 | |
#define _LIBCPP_HAS_NO_NULLPTR | |
#endif | |
#if _GNUC_VER < 407 | |
#define _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS | |
#endif | |
#endif // __GXX_EXPERIMENTAL_CXX0X__ | |
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE { | |
#define _LIBCPP_END_NAMESPACE_STD } } | |
#define _VSTD std::_LIBCPP_NAMESPACE | |
namespace std { | |
namespace _LIBCPP_NAMESPACE { | |
} | |
using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); | |
} | |
#if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__) | |
#define _LIBCPP_HAS_NO_ASAN | |
#endif | |
#elif defined(_LIBCPP_MSVC) | |
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES | |
#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER | |
#define _LIBCPP_HAS_NO_CONSTEXPR | |
#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR | |
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES | |
#define _LIBCPP_HAS_NO_UNICODE_CHARS | |
#define _LIBCPP_HAS_NO_DELETED_FUNCTIONS | |
#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS | |
#define __alignof__ __alignof | |
#define _LIBCPP_NORETURN __declspec(noreturn) | |
#define _LIBCPP_UNUSED | |
#define _ALIGNAS(x) __declspec(align(x)) | |
#define _LIBCPP_HAS_NO_VARIADICS | |
#define _NOEXCEPT throw () | |
#define _NOEXCEPT_(x) | |
#define _NOEXCEPT_OR_FALSE(x) false | |
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { | |
#define _LIBCPP_END_NAMESPACE_STD } | |
#define _VSTD std | |
# define _LIBCPP_WEAK | |
namespace std { | |
} | |
#define _LIBCPP_HAS_NO_ASAN | |
#elif defined(__IBMCPP__) | |
#define _ALIGNAS(x) __attribute__((__aligned__(x))) | |
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) | |
#define _ATTRIBUTE(x) __attribute__((x)) | |
#define _LIBCPP_NORETURN __attribute__((noreturn)) | |
#define _LIBCPP_UNUSED | |
#define _NOEXCEPT throw() | |
#define _NOEXCEPT_(x) | |
#define _NOEXCEPT_OR_FALSE(x) false | |
#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES | |
#define _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS | |
#define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS | |
#define _LIBCPP_HAS_NO_NULLPTR | |
#define _LIBCPP_HAS_NO_UNICODE_CHARS | |
#define _LIBCPP_HAS_IS_BASE_OF | |
#define _LIBCPP_HAS_IS_FINAL | |
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES | |
#if defined(_AIX) | |
#define __MULTILOCALE_API | |
#endif | |
#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { | |
#define _LIBCPP_END_NAMESPACE_STD } } | |
#define _VSTD std::_LIBCPP_NAMESPACE | |
namespace std { | |
inline namespace _LIBCPP_NAMESPACE { | |
} | |
} | |
#define _LIBCPP_HAS_NO_ASAN | |
#endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__ | |
#ifdef _LIBCPP_HAS_NO_UNICODE_CHARS | |
typedef unsigned short char16_t; | |
typedef unsigned int char32_t; | |
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS | |
#ifndef __SIZEOF_INT128__ | |
#define _LIBCPP_HAS_NO_INT128 | |
#endif | |
#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT | |
template <bool> struct __static_assert_test; | |
template <> struct __static_assert_test<true> {}; | |
template <unsigned> struct __static_assert_check {}; | |
#define static_assert(__b, __m) \ | |
typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \ | |
_LIBCPP_CONCAT(__t, __LINE__) | |
#endif // _LIBCPP_HAS_NO_STATIC_ASSERT | |
#ifdef _LIBCPP_HAS_NO_DECLTYPE | |
// GCC 4.6 provides __decltype in all standard modes. | |
#if !__is_identifier(__decltype) || _GNUC_VER >= 406 | |
# define decltype(__x) __decltype(__x) | |
#else | |
# define decltype(__x) __typeof__(__x) | |
#endif | |
#endif | |
#ifdef _LIBCPP_HAS_NO_CONSTEXPR | |
#define _LIBCPP_CONSTEXPR | |
#else | |
#define _LIBCPP_CONSTEXPR constexpr | |
#endif | |
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS | |
#define _LIBCPP_DEFAULT {} | |
#else | |
#define _LIBCPP_DEFAULT = default; | |
#endif | |
#ifdef __GNUC__ | |
#define _NOALIAS __attribute__((__malloc__)) | |
#else | |
#define _NOALIAS | |
#endif | |
#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) | |
# define _LIBCPP_EXPLICIT explicit | |
#else | |
# define _LIBCPP_EXPLICIT | |
#endif | |
#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete) | |
# define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE | |
#endif | |
#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS | |
#define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx | |
#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ | |
__lx __v_; \ | |
_LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \ | |
_LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ | |
_LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \ | |
}; | |
#else // _LIBCPP_HAS_NO_STRONG_ENUMS | |
#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_TYPE_VIS x | |
#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) | |
#endif // _LIBCPP_HAS_NO_STRONG_ENUMS | |
#ifdef _LIBCPP_DEBUG | |
# if _LIBCPP_DEBUG == 0 | |
# define _LIBCPP_DEBUG_LEVEL 1 | |
# elif _LIBCPP_DEBUG == 1 | |
# define _LIBCPP_DEBUG_LEVEL 2 | |
# else | |
# error Supported values for _LIBCPP_DEBUG are 0 and 1 | |
# endif | |
# define _LIBCPP_EXTERN_TEMPLATE(...) | |
#endif | |
#ifndef _LIBCPP_EXTERN_TEMPLATE | |
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; | |
#endif | |
#ifndef _LIBCPP_EXTERN_TEMPLATE2 | |
#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__; | |
#endif | |
#if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) | |
#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63) | |
#endif | |
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \ | |
defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__) | |
#define _LIBCPP_LOCALE__L_EXTENSIONS 1 | |
#endif | |
#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) && \ | |
!defined(__CloudABI__) | |
#define _LIBCPP_HAS_CATOPEN 1 | |
#endif | |
#ifdef __FreeBSD__ | |
#define _DECLARE_C99_LDBL_MATH 1 | |
#endif | |
#if defined(__APPLE__) || defined(__FreeBSD__) | |
#define _LIBCPP_HAS_DEFAULTRUNELOCALE | |
#endif | |
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) | |
#define _LIBCPP_WCTYPE_IS_MASK | |
#endif | |
#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR | |
# define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1 | |
#endif | |
#ifndef _LIBCPP_STD_VER | |
# if __cplusplus <= 201103L | |
# define _LIBCPP_STD_VER 11 | |
# elif __cplusplus <= 201402L | |
# define _LIBCPP_STD_VER 14 | |
# else | |
# define _LIBCPP_STD_VER 15 // current year, or date of c++17 ratification | |
# endif | |
#endif // _LIBCPP_STD_VER | |
#if _LIBCPP_STD_VER > 11 | |
#define _LIBCPP_DEPRECATED [[deprecated]] | |
#else | |
#define _LIBCPP_DEPRECATED | |
#endif | |
#if _LIBCPP_STD_VER <= 11 | |
#define _LIBCPP_EXPLICIT_AFTER_CXX11 | |
#define _LIBCPP_DEPRECATED_AFTER_CXX11 | |
#else | |
#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit | |
#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]] | |
#endif | |
#if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) | |
#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr | |
#else | |
#define _LIBCPP_CONSTEXPR_AFTER_CXX11 | |
#endif | |
#ifndef _LIBCPP_HAS_NO_ASAN | |
extern "C" void __sanitizer_annotate_contiguous_container( | |
const void *, const void *, const void *, const void *); | |
#endif | |
// Try to find out if RTTI is disabled. | |
// g++ and cl.exe have RTTI on by default and define a macro when it is. | |
// g++ only defines the macro in 4.3.2 and onwards. | |
#if !defined(_LIBCPP_NO_RTTI) | |
# if defined(__GNUG__) && ((__GNUC__ >= 5) || (__GNUC__ == 4 && \ | |
(__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && !defined(__GXX_RTTI) | |
# define _LIBCPP_NO_RTTI | |
# elif (defined(_MSC_VER) && !defined(__clang__)) && !defined(_CPPRTTI) | |
# define _LIBCPP_NO_RTTI | |
# endif | |
#endif | |
#ifndef _LIBCPP_WEAK | |
# define _LIBCPP_WEAK __attribute__((__weak__)) | |
#endif | |
+// Thread API | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+# ifndef _LIBCPP_THREAD_API | |
+# error "No thread API" | |
+# endif // _LIBCPP_THREAD_API | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+ | |
#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) | |
# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ | |
_LIBCPP_HAS_NO_THREADS is defined. | |
#endif | |
// Systems that use capability-based security (FreeBSD with Capsicum, | |
// Nuxi CloudABI) may only provide local filesystem access (using *at()). | |
// Functions like open(), rename(), unlink() and stat() should not be | |
// used, as they attempt to access the global filesystem namespace. | |
#ifdef __CloudABI__ | |
#define _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE | |
#endif | |
// CloudABI is intended for running networked services. Processes do not | |
// have standard input and output channels. | |
#ifdef __CloudABI__ | |
#define _LIBCPP_HAS_NO_STDIN | |
#define _LIBCPP_HAS_NO_STDOUT | |
#endif | |
#if defined(__ANDROID__) || defined(__CloudABI__) | |
#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE | |
#endif | |
// Thread-unsafe functions such as strtok(), mbtowc() and localtime() | |
// are not available. | |
#ifdef __CloudABI__ | |
#define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS | |
#endif | |
#endif // _LIBCPP_CONFIG | |
diff --git a/include/__mutex_base b/include/__mutex_base | |
index d5ece7c..e5a4353 100644 | |
--- a/include/__mutex_base | |
+++ b/include/__mutex_base | |
@@ -1,407 +1,410 @@ | |
// -*- C++ -*- | |
//===----------------------------------------------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#ifndef _LIBCPP___MUTEX_BASE | |
#define _LIBCPP___MUTEX_BASE | |
#include <__config> | |
#include <chrono> | |
#include <system_error> | |
-#include <pthread.h> | |
+#include <support/mutex.h> | |
+#include <support/condition_variable.h> | |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
#pragma GCC system_header | |
#endif | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
class _LIBCPP_TYPE_VIS mutex | |
{ | |
- pthread_mutex_t __m_; | |
+ typedef __libcpp_support::__os_mutex __mutex_type; | |
+ __mutex_type __m_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
#ifndef _LIBCPP_HAS_NO_CONSTEXPR | |
- constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {} | |
+ constexpr mutex() _NOEXCEPT : __m_(__libcpp_support::__os_mutex_init) {} | |
#else | |
- mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;} | |
+ mutex() _NOEXCEPT {__m_ = __libcpp_support::__os_mutex_init;} | |
#endif | |
~mutex(); | |
private: | |
mutex(const mutex&);// = delete; | |
mutex& operator=(const mutex&);// = delete; | |
public: | |
void lock(); | |
bool try_lock() _NOEXCEPT; | |
void unlock() _NOEXCEPT; | |
- typedef pthread_mutex_t* native_handle_type; | |
+ typedef __mutex_type* native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} | |
}; | |
struct _LIBCPP_TYPE_VIS defer_lock_t {}; | |
struct _LIBCPP_TYPE_VIS try_to_lock_t {}; | |
struct _LIBCPP_TYPE_VIS adopt_lock_t {}; | |
#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MUTEX) | |
extern const defer_lock_t defer_lock; | |
extern const try_to_lock_t try_to_lock; | |
extern const adopt_lock_t adopt_lock; | |
#else | |
constexpr defer_lock_t defer_lock = defer_lock_t(); | |
constexpr try_to_lock_t try_to_lock = try_to_lock_t(); | |
constexpr adopt_lock_t adopt_lock = adopt_lock_t(); | |
#endif | |
template <class _Mutex> | |
class _LIBCPP_TYPE_VIS_ONLY lock_guard | |
{ | |
public: | |
typedef _Mutex mutex_type; | |
private: | |
mutex_type& __m_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
explicit lock_guard(mutex_type& __m) | |
: __m_(__m) {__m_.lock();} | |
_LIBCPP_INLINE_VISIBILITY | |
lock_guard(mutex_type& __m, adopt_lock_t) | |
: __m_(__m) {} | |
_LIBCPP_INLINE_VISIBILITY | |
~lock_guard() {__m_.unlock();} | |
private: | |
lock_guard(lock_guard const&);// = delete; | |
lock_guard& operator=(lock_guard const&);// = delete; | |
}; | |
template <class _Mutex> | |
class _LIBCPP_TYPE_VIS_ONLY unique_lock | |
{ | |
public: | |
typedef _Mutex mutex_type; | |
private: | |
mutex_type* __m_; | |
bool __owns_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} | |
_LIBCPP_INLINE_VISIBILITY | |
explicit unique_lock(mutex_type& __m) | |
: __m_(&__m), __owns_(true) {__m_->lock();} | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT | |
: __m_(&__m), __owns_(false) {} | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock(mutex_type& __m, try_to_lock_t) | |
: __m_(&__m), __owns_(__m.try_lock()) {} | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock(mutex_type& __m, adopt_lock_t) | |
: __m_(&__m), __owns_(true) {} | |
template <class _Clock, class _Duration> | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) | |
: __m_(&__m), __owns_(__m.try_lock_until(__t)) {} | |
template <class _Rep, class _Period> | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) | |
: __m_(&__m), __owns_(__m.try_lock_for(__d)) {} | |
_LIBCPP_INLINE_VISIBILITY | |
~unique_lock() | |
{ | |
if (__owns_) | |
__m_->unlock(); | |
} | |
private: | |
unique_lock(unique_lock const&); // = delete; | |
unique_lock& operator=(unique_lock const&); // = delete; | |
public: | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock(unique_lock&& __u) _NOEXCEPT | |
: __m_(__u.__m_), __owns_(__u.__owns_) | |
{__u.__m_ = nullptr; __u.__owns_ = false;} | |
_LIBCPP_INLINE_VISIBILITY | |
unique_lock& operator=(unique_lock&& __u) _NOEXCEPT | |
{ | |
if (__owns_) | |
__m_->unlock(); | |
__m_ = __u.__m_; | |
__owns_ = __u.__owns_; | |
__u.__m_ = nullptr; | |
__u.__owns_ = false; | |
return *this; | |
} | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
void lock(); | |
bool try_lock(); | |
template <class _Rep, class _Period> | |
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); | |
template <class _Clock, class _Duration> | |
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | |
void unlock(); | |
_LIBCPP_INLINE_VISIBILITY | |
void swap(unique_lock& __u) _NOEXCEPT | |
{ | |
_VSTD::swap(__m_, __u.__m_); | |
_VSTD::swap(__owns_, __u.__owns_); | |
} | |
_LIBCPP_INLINE_VISIBILITY | |
mutex_type* release() _NOEXCEPT | |
{ | |
mutex_type* __m = __m_; | |
__m_ = nullptr; | |
__owns_ = false; | |
return __m; | |
} | |
_LIBCPP_INLINE_VISIBILITY | |
bool owns_lock() const _NOEXCEPT {return __owns_;} | |
_LIBCPP_INLINE_VISIBILITY | |
_LIBCPP_EXPLICIT | |
operator bool () const _NOEXCEPT {return __owns_;} | |
_LIBCPP_INLINE_VISIBILITY | |
mutex_type* mutex() const _NOEXCEPT {return __m_;} | |
}; | |
template <class _Mutex> | |
void | |
unique_lock<_Mutex>::lock() | |
{ | |
if (__m_ == nullptr) | |
__throw_system_error(EPERM, "unique_lock::lock: references null mutex"); | |
if (__owns_) | |
__throw_system_error(EDEADLK, "unique_lock::lock: already locked"); | |
__m_->lock(); | |
__owns_ = true; | |
} | |
template <class _Mutex> | |
bool | |
unique_lock<_Mutex>::try_lock() | |
{ | |
if (__m_ == nullptr) | |
__throw_system_error(EPERM, "unique_lock::try_lock: references null mutex"); | |
if (__owns_) | |
__throw_system_error(EDEADLK, "unique_lock::try_lock: already locked"); | |
__owns_ = __m_->try_lock(); | |
return __owns_; | |
} | |
template <class _Mutex> | |
template <class _Rep, class _Period> | |
bool | |
unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) | |
{ | |
if (__m_ == nullptr) | |
__throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex"); | |
if (__owns_) | |
__throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked"); | |
__owns_ = __m_->try_lock_for(__d); | |
return __owns_; | |
} | |
template <class _Mutex> | |
template <class _Clock, class _Duration> | |
bool | |
unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | |
{ | |
if (__m_ == nullptr) | |
__throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex"); | |
if (__owns_) | |
__throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked"); | |
__owns_ = __m_->try_lock_until(__t); | |
return __owns_; | |
} | |
template <class _Mutex> | |
void | |
unique_lock<_Mutex>::unlock() | |
{ | |
if (!__owns_) | |
__throw_system_error(EPERM, "unique_lock::unlock: not locked"); | |
__m_->unlock(); | |
__owns_ = false; | |
} | |
template <class _Mutex> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT | |
{__x.swap(__y);} | |
//enum class cv_status | |
_LIBCPP_DECLARE_STRONG_ENUM(cv_status) | |
{ | |
no_timeout, | |
timeout | |
}; | |
_LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) | |
class _LIBCPP_TYPE_VIS condition_variable | |
{ | |
- pthread_cond_t __cv_; | |
+ typedef __libcpp_support::__os_cond_var __cond_var_type; | |
+ __cond_var_type __cv_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
#ifndef _LIBCPP_HAS_NO_CONSTEXPR | |
- constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {} | |
+ constexpr condition_variable() : __cv_(__libcpp_support::__os_cond_var_init) {} | |
#else | |
- condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;} | |
+ condition_variable() {__cv_ = __libcpp_support::__os_cond_var_init;} | |
#endif | |
~condition_variable(); | |
private: | |
condition_variable(const condition_variable&); // = delete; | |
condition_variable& operator=(const condition_variable&); // = delete; | |
public: | |
void notify_one() _NOEXCEPT; | |
void notify_all() _NOEXCEPT; | |
void wait(unique_lock<mutex>& __lk) _NOEXCEPT; | |
template <class _Predicate> | |
void wait(unique_lock<mutex>& __lk, _Predicate __pred); | |
template <class _Clock, class _Duration> | |
cv_status | |
wait_until(unique_lock<mutex>& __lk, | |
const chrono::time_point<_Clock, _Duration>& __t); | |
template <class _Clock, class _Duration, class _Predicate> | |
bool | |
wait_until(unique_lock<mutex>& __lk, | |
const chrono::time_point<_Clock, _Duration>& __t, | |
_Predicate __pred); | |
template <class _Rep, class _Period> | |
cv_status | |
wait_for(unique_lock<mutex>& __lk, | |
const chrono::duration<_Rep, _Period>& __d); | |
template <class _Rep, class _Period, class _Predicate> | |
bool | |
wait_for(unique_lock<mutex>& __lk, | |
const chrono::duration<_Rep, _Period>& __d, | |
_Predicate __pred); | |
- typedef pthread_cond_t* native_handle_type; | |
+ typedef __cond_var_type* native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} | |
private: | |
void __do_timed_wait(unique_lock<mutex>& __lk, | |
chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT; | |
}; | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
template <class _To, class _Rep, class _Period> | |
inline _LIBCPP_INLINE_VISIBILITY | |
typename enable_if | |
< | |
chrono::__is_duration<_To>::value, | |
_To | |
>::type | |
__ceil(chrono::duration<_Rep, _Period> __d) | |
{ | |
using namespace chrono; | |
_To __r = duration_cast<_To>(__d); | |
if (__r < __d) | |
++__r; | |
return __r; | |
} | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
template <class _Predicate> | |
void | |
condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) | |
{ | |
while (!__pred()) | |
wait(__lk); | |
} | |
template <class _Clock, class _Duration> | |
cv_status | |
condition_variable::wait_until(unique_lock<mutex>& __lk, | |
const chrono::time_point<_Clock, _Duration>& __t) | |
{ | |
using namespace chrono; | |
wait_for(__lk, __t - _Clock::now()); | |
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; | |
} | |
template <class _Clock, class _Duration, class _Predicate> | |
bool | |
condition_variable::wait_until(unique_lock<mutex>& __lk, | |
const chrono::time_point<_Clock, _Duration>& __t, | |
_Predicate __pred) | |
{ | |
while (!__pred()) | |
{ | |
if (wait_until(__lk, __t) == cv_status::timeout) | |
return __pred(); | |
} | |
return true; | |
} | |
template <class _Rep, class _Period> | |
cv_status | |
condition_variable::wait_for(unique_lock<mutex>& __lk, | |
const chrono::duration<_Rep, _Period>& __d) | |
{ | |
using namespace chrono; | |
if (__d <= __d.zero()) | |
return cv_status::timeout; | |
typedef time_point<system_clock, duration<long double, nano> > __sys_tpf; | |
typedef time_point<system_clock, nanoseconds> __sys_tpi; | |
__sys_tpf _Max = __sys_tpi::max(); | |
system_clock::time_point __s_now = system_clock::now(); | |
steady_clock::time_point __c_now = steady_clock::now(); | |
if (_Max - __d > __s_now) | |
__do_timed_wait(__lk, __s_now + __ceil<nanoseconds>(__d)); | |
else | |
__do_timed_wait(__lk, __sys_tpi::max()); | |
return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : | |
cv_status::timeout; | |
} | |
template <class _Rep, class _Period, class _Predicate> | |
inline _LIBCPP_INLINE_VISIBILITY | |
bool | |
condition_variable::wait_for(unique_lock<mutex>& __lk, | |
const chrono::duration<_Rep, _Period>& __d, | |
_Predicate __pred) | |
{ | |
return wait_until(__lk, chrono::steady_clock::now() + __d, | |
_VSTD::move(__pred)); | |
} | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // _LIBCPP___MUTEX_BASE | |
diff --git a/include/mutex b/include/mutex | |
index 373d75b..cbda79c 100644 | |
--- a/include/mutex | |
+++ b/include/mutex | |
@@ -1,582 +1,582 @@ | |
// -*- C++ -*- | |
//===--------------------------- mutex ------------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#ifndef _LIBCPP_MUTEX | |
#define _LIBCPP_MUTEX | |
/* | |
mutex synopsis | |
namespace std | |
{ | |
class mutex | |
{ | |
public: | |
constexpr mutex() noexcept; | |
~mutex(); | |
mutex(const mutex&) = delete; | |
mutex& operator=(const mutex&) = delete; | |
void lock(); | |
bool try_lock(); | |
void unlock(); | |
typedef pthread_mutex_t* native_handle_type; | |
native_handle_type native_handle(); | |
}; | |
class recursive_mutex | |
{ | |
public: | |
recursive_mutex(); | |
~recursive_mutex(); | |
recursive_mutex(const recursive_mutex&) = delete; | |
recursive_mutex& operator=(const recursive_mutex&) = delete; | |
void lock(); | |
bool try_lock() noexcept; | |
void unlock(); | |
typedef pthread_mutex_t* native_handle_type; | |
native_handle_type native_handle(); | |
}; | |
class timed_mutex | |
{ | |
public: | |
timed_mutex(); | |
~timed_mutex(); | |
timed_mutex(const timed_mutex&) = delete; | |
timed_mutex& operator=(const timed_mutex&) = delete; | |
void lock(); | |
bool try_lock(); | |
template <class Rep, class Period> | |
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | |
template <class Clock, class Duration> | |
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | |
void unlock(); | |
}; | |
class recursive_timed_mutex | |
{ | |
public: | |
recursive_timed_mutex(); | |
~recursive_timed_mutex(); | |
recursive_timed_mutex(const recursive_timed_mutex&) = delete; | |
recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; | |
void lock(); | |
bool try_lock() noexcept; | |
template <class Rep, class Period> | |
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | |
template <class Clock, class Duration> | |
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | |
void unlock(); | |
}; | |
struct defer_lock_t {}; | |
struct try_to_lock_t {}; | |
struct adopt_lock_t {}; | |
constexpr defer_lock_t defer_lock{}; | |
constexpr try_to_lock_t try_to_lock{}; | |
constexpr adopt_lock_t adopt_lock{}; | |
template <class Mutex> | |
class lock_guard | |
{ | |
public: | |
typedef Mutex mutex_type; | |
explicit lock_guard(mutex_type& m); | |
lock_guard(mutex_type& m, adopt_lock_t); | |
~lock_guard(); | |
lock_guard(lock_guard const&) = delete; | |
lock_guard& operator=(lock_guard const&) = delete; | |
}; | |
template <class Mutex> | |
class unique_lock | |
{ | |
public: | |
typedef Mutex mutex_type; | |
unique_lock() noexcept; | |
explicit unique_lock(mutex_type& m); | |
unique_lock(mutex_type& m, defer_lock_t) noexcept; | |
unique_lock(mutex_type& m, try_to_lock_t); | |
unique_lock(mutex_type& m, adopt_lock_t); | |
template <class Clock, class Duration> | |
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); | |
template <class Rep, class Period> | |
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); | |
~unique_lock(); | |
unique_lock(unique_lock const&) = delete; | |
unique_lock& operator=(unique_lock const&) = delete; | |
unique_lock(unique_lock&& u) noexcept; | |
unique_lock& operator=(unique_lock&& u) noexcept; | |
void lock(); | |
bool try_lock(); | |
template <class Rep, class Period> | |
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); | |
template <class Clock, class Duration> | |
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); | |
void unlock(); | |
void swap(unique_lock& u) noexcept; | |
mutex_type* release() noexcept; | |
bool owns_lock() const noexcept; | |
explicit operator bool () const noexcept; | |
mutex_type* mutex() const noexcept; | |
}; | |
template <class Mutex> | |
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept; | |
template <class L1, class L2, class... L3> | |
int try_lock(L1&, L2&, L3&...); | |
template <class L1, class L2, class... L3> | |
void lock(L1&, L2&, L3&...); | |
struct once_flag | |
{ | |
constexpr once_flag() noexcept; | |
once_flag(const once_flag&) = delete; | |
once_flag& operator=(const once_flag&) = delete; | |
}; | |
template<class Callable, class ...Args> | |
void call_once(once_flag& flag, Callable&& func, Args&&... args); | |
} // std | |
*/ | |
#include <__config> | |
#include <__mutex_base> | |
#include <functional> | |
#include <memory> | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
#include <tuple> | |
#endif | |
-#include <sched.h> | |
+#include <support/thread.h> | |
#include <__undef_min_max> | |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
#pragma GCC system_header | |
#endif | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
class _LIBCPP_TYPE_VIS recursive_mutex | |
{ | |
- pthread_mutex_t __m_; | |
+ typedef __libcpp_support::__os_mutex __mutex_type; | |
+ __mutex_type __m_; | |
public: | |
recursive_mutex(); | |
~recursive_mutex(); | |
private: | |
recursive_mutex(const recursive_mutex&); // = delete; | |
recursive_mutex& operator=(const recursive_mutex&); // = delete; | |
public: | |
void lock(); | |
bool try_lock() _NOEXCEPT; | |
- void unlock() _NOEXCEPT; | |
+ void unlock() _NOEXCEPT; | |
- typedef pthread_mutex_t* native_handle_type; | |
+ typedef __mutex_type* native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY | |
native_handle_type native_handle() {return &__m_;} | |
}; | |
class _LIBCPP_TYPE_VIS timed_mutex | |
{ | |
mutex __m_; | |
condition_variable __cv_; | |
bool __locked_; | |
public: | |
timed_mutex(); | |
~timed_mutex(); | |
private: | |
timed_mutex(const timed_mutex&); // = delete; | |
timed_mutex& operator=(const timed_mutex&); // = delete; | |
public: | |
void lock(); | |
bool try_lock() _NOEXCEPT; | |
template <class _Rep, class _Period> | |
_LIBCPP_INLINE_VISIBILITY | |
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) | |
{return try_lock_until(chrono::steady_clock::now() + __d);} | |
template <class _Clock, class _Duration> | |
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | |
void unlock() _NOEXCEPT; | |
}; | |
template <class _Clock, class _Duration> | |
bool | |
timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | |
{ | |
using namespace chrono; | |
unique_lock<mutex> __lk(__m_); | |
bool no_timeout = _Clock::now() < __t; | |
while (no_timeout && __locked_) | |
no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; | |
if (!__locked_) | |
{ | |
__locked_ = true; | |
return true; | |
} | |
return false; | |
} | |
class _LIBCPP_TYPE_VIS recursive_timed_mutex | |
{ | |
- mutex __m_; | |
- condition_variable __cv_; | |
- size_t __count_; | |
- pthread_t __id_; | |
+ mutex __m_; | |
+ condition_variable __cv_; | |
+ size_t __count_; | |
+ __libcpp_support::__os_thread_id __id_; | |
public: | |
recursive_timed_mutex(); | |
~recursive_timed_mutex(); | |
private: | |
recursive_timed_mutex(const recursive_timed_mutex&); // = delete; | |
recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete; | |
public: | |
void lock(); | |
bool try_lock() _NOEXCEPT; | |
template <class _Rep, class _Period> | |
_LIBCPP_INLINE_VISIBILITY | |
bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) | |
{return try_lock_until(chrono::steady_clock::now() + __d);} | |
template <class _Clock, class _Duration> | |
bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | |
void unlock() _NOEXCEPT; | |
}; | |
template <class _Clock, class _Duration> | |
bool | |
recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | |
{ | |
using namespace chrono; | |
- pthread_t __id = pthread_self(); | |
+ using namespace __libcpp_support; | |
+ __os_thread_id __id = __os_get_current_thread_id(); | |
unique_lock<mutex> lk(__m_); | |
- if (pthread_equal(__id, __id_)) | |
+ if (__os_thread_id_compare(__id, __id_) == 0) | |
{ | |
if (__count_ == numeric_limits<size_t>::max()) | |
return false; | |
++__count_; | |
return true; | |
} | |
bool no_timeout = _Clock::now() < __t; | |
while (no_timeout && __count_ != 0) | |
no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; | |
if (__count_ == 0) | |
{ | |
__count_ = 1; | |
__id_ = __id; | |
return true; | |
} | |
return false; | |
} | |
template <class _L0, class _L1> | |
int | |
try_lock(_L0& __l0, _L1& __l1) | |
{ | |
unique_lock<_L0> __u0(__l0, try_to_lock); | |
if (__u0.owns_lock()) | |
{ | |
if (__l1.try_lock()) | |
{ | |
__u0.release(); | |
return -1; | |
} | |
else | |
return 1; | |
} | |
return 0; | |
} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _L0, class _L1, class _L2, class... _L3> | |
int | |
try_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) | |
{ | |
int __r = 0; | |
unique_lock<_L0> __u0(__l0, try_to_lock); | |
if (__u0.owns_lock()) | |
{ | |
__r = try_lock(__l1, __l2, __l3...); | |
if (__r == -1) | |
__u0.release(); | |
else | |
++__r; | |
} | |
return __r; | |
} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
template <class _L0, class _L1> | |
void | |
lock(_L0& __l0, _L1& __l1) | |
{ | |
while (true) | |
{ | |
{ | |
unique_lock<_L0> __u0(__l0); | |
if (__l1.try_lock()) | |
{ | |
__u0.release(); | |
break; | |
} | |
} | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
{ | |
unique_lock<_L1> __u1(__l1); | |
if (__l0.try_lock()) | |
{ | |
__u1.release(); | |
break; | |
} | |
} | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
} | |
} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _L0, class _L1, class _L2, class ..._L3> | |
void | |
__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) | |
{ | |
while (true) | |
{ | |
switch (__i) | |
{ | |
case 0: | |
{ | |
unique_lock<_L0> __u0(__l0); | |
__i = try_lock(__l1, __l2, __l3...); | |
if (__i == -1) | |
{ | |
__u0.release(); | |
return; | |
} | |
} | |
++__i; | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
break; | |
case 1: | |
{ | |
unique_lock<_L1> __u1(__l1); | |
__i = try_lock(__l2, __l3..., __l0); | |
if (__i == -1) | |
{ | |
__u1.release(); | |
return; | |
} | |
} | |
if (__i == sizeof...(_L3) + 1) | |
__i = 0; | |
else | |
__i += 2; | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
break; | |
default: | |
__lock_first(__i - 2, __l2, __l3..., __l0, __l1); | |
return; | |
} | |
} | |
} | |
template <class _L0, class _L1, class _L2, class ..._L3> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) | |
{ | |
__lock_first(0, __l0, __l1, __l2, __l3...); | |
} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
struct _LIBCPP_TYPE_VIS_ONLY once_flag; | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable, class... _Args> | |
_LIBCPP_INLINE_VISIBILITY | |
void call_once(once_flag&, _Callable&&, _Args&&...); | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable> | |
_LIBCPP_INLINE_VISIBILITY | |
void call_once(once_flag&, _Callable&); | |
template<class _Callable> | |
_LIBCPP_INLINE_VISIBILITY | |
void call_once(once_flag&, const _Callable&); | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
struct _LIBCPP_TYPE_VIS_ONLY once_flag | |
{ | |
_LIBCPP_INLINE_VISIBILITY | |
_LIBCPP_CONSTEXPR | |
once_flag() _NOEXCEPT : __state_(0) {} | |
private: | |
once_flag(const once_flag&); // = delete; | |
once_flag& operator=(const once_flag&); // = delete; | |
unsigned long __state_; | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable, class... _Args> | |
friend | |
void call_once(once_flag&, _Callable&&, _Args&&...); | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable> | |
friend | |
void call_once(once_flag&, _Callable&); | |
template<class _Callable> | |
friend | |
void call_once(once_flag&, const _Callable&); | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
}; | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fp> | |
class __call_once_param | |
{ | |
_Fp& __f_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
explicit __call_once_param(_Fp& __f) : __f_(__f) {} | |
_LIBCPP_INLINE_VISIBILITY | |
void operator()() | |
{ | |
typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; | |
__execute(_Index()); | |
} | |
private: | |
template <size_t ..._Indices> | |
_LIBCPP_INLINE_VISIBILITY | |
void __execute(__tuple_indices<_Indices...>) | |
{ | |
__invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...); | |
} | |
}; | |
#else | |
template <class _Fp> | |
class __call_once_param | |
{ | |
_Fp& __f_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
explicit __call_once_param(_Fp& __f) : __f_(__f) {} | |
_LIBCPP_INLINE_VISIBILITY | |
void operator()() | |
{ | |
__f_(); | |
} | |
}; | |
#endif | |
template <class _Fp> | |
void | |
__call_once_proxy(void* __vp) | |
{ | |
__call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); | |
(*__p)(); | |
} | |
-_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*)); | |
- | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable, class... _Args> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) | |
{ | |
if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) | |
{ | |
typedef tuple<_Callable&&, _Args&&...> _Gp; | |
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); | |
__call_once_param<_Gp> __p(__f); | |
- __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); | |
+ __libcpp_support::__os_call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); | |
} | |
} | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
call_once(once_flag& __flag, _Callable& __func) | |
{ | |
if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) | |
{ | |
__call_once_param<_Callable> __p(__func); | |
- __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); | |
+ __libcpp_support::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); | |
} | |
} | |
template<class _Callable> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
call_once(once_flag& __flag, const _Callable& __func) | |
{ | |
if (__flag.__state_ != ~0ul) | |
{ | |
__call_once_param<const _Callable> __p(__func); | |
- __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); | |
+ __libcpp_support::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); | |
} | |
} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // _LIBCPP_MUTEX | |
diff --git a/include/support/condition_variable.h b/include/support/condition_variable.h | |
new file mode 100644 | |
index 0000000..03fe9ed | |
--- /dev/null | |
+++ b/include/support/condition_variable.h | |
@@ -0,0 +1,28 @@ | |
+// -*- C++ -*- | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef _LIBCPP_SUPPORT_CONDITION_VARIABLE_H | |
+#define _LIBCPP_SUPPORT_CONDITION_VARIABLE_H | |
+ | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+ | |
+#define _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#if _LIBCPP_THREAD_API == _LIBCPP_PTHREAD | |
+# include <support/pthread/condition_variable.h> | |
+#else | |
+# error "No thread API found" | |
+#endif // _LIBCPP_THREAD_API == _LIBCPP_PTHREAD | |
+ | |
+#undef _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+ | |
+#endif // _LIBCPP_SUPPORT_CONDITION_VARIABLE_H | |
diff --git a/include/support/mutex.h b/include/support/mutex.h | |
new file mode 100644 | |
index 0000000..87af82e | |
--- /dev/null | |
+++ b/include/support/mutex.h | |
@@ -0,0 +1,28 @@ | |
+// -*- C++ -*- | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef _LIBCPP_SUPPORT_MUTEX_H | |
+#define _LIBCPP_SUPPORT_MUTEX_H | |
+ | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+ | |
+#define _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#if _LIBCPP_THREAD_API == _LIBCPP_PTHREAD | |
+# include <support/pthread/mutex.h> | |
+#else | |
+# error "No thread API found" | |
+#endif // _LIBCPP_THREAD_API == _LIBCPP_PTHREAD | |
+ | |
+#undef _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+ | |
+#endif // _LIBCPP_SUPPORT_MUTEX_H | |
diff --git a/include/support/pthread/condition_variable.h b/include/support/pthread/condition_variable.h | |
new file mode 100644 | |
index 0000000..908ddbc | |
--- /dev/null | |
+++ b/include/support/pthread/condition_variable.h | |
@@ -0,0 +1,62 @@ | |
+// -*- C++ -*- | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef _LIBCPP_SUPPORT_PTHREAD_CONDITION_VARIABLE_H | |
+#define _LIBCPP_SUPPORT_PTHREAD_CONDITION_VARIABLE_H | |
+ | |
+#ifndef _LIBCPP_INCLUDE_THREAD_API | |
+# error "This header can't be included directly" | |
+#endif // _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#include <pthread.h> | |
+ | |
+_LIBCPP_BEGIN_NAMESPACE_STD | |
+ | |
+namespace __libcpp_support | |
+{ | |
+ | |
+typedef pthread_cond_t __os_cond_var; | |
+typedef pthread_mutex_t __os_mutex; | |
+_LIBCPP_CONSTEXPR pthread_cond_t __os_cond_var_init = PTHREAD_COND_INITIALIZER; | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void __os_cond_var_destroy(__os_cond_var* __cv) | |
+{ | |
+ pthread_cond_destroy(__cv); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void __os_cond_var_notify_one(__os_cond_var* __cv) | |
+{ | |
+ pthread_cond_signal(__cv); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void __os_cond_var_notify_all(__os_cond_var* __cv) | |
+{ | |
+ pthread_cond_broadcast(__cv); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_cond_var_wait(__os_cond_var* __cv, __os_mutex* __m) | |
+{ | |
+ return pthread_cond_wait(__cv, __m); | |
+} | |
+ | |
+_LIBCPP_FUNC_VIS | |
+void __os_cond_var_timed_wait(__os_cond_var* __cv, | |
+ __os_mutex* __m, | |
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp); | |
+ | |
+} // namespace __libcpp_support | |
+ | |
+_LIBCPP_END_NAMESPACE_STD | |
+ | |
+#endif // _LIBCPP_SUPPORT_PTHREAD_CONDITION_VARIABLE_H | |
diff --git a/include/support/pthread/mutex.h b/include/support/pthread/mutex.h | |
new file mode 100644 | |
index 0000000..137084e | |
--- /dev/null | |
+++ b/include/support/pthread/mutex.h | |
@@ -0,0 +1,93 @@ | |
+// -*- C++ -*- | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef _LIBCPP_SUPPORT_PTHREAD_MUTEX_H | |
+#define _LIBCPP_SUPPORT_PTHREAD_MUTEX_H | |
+ | |
+#ifndef _LIBCPP_INCLUDE_THREAD_API | |
+# error "This header can't be included directly" | |
+#endif // _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#include <pthread.h> | |
+ | |
+_LIBCPP_BEGIN_NAMESPACE_STD | |
+ | |
+namespace __libcpp_support | |
+{ | |
+ | |
+// mutex | |
+typedef pthread_mutex_t __os_mutex; | |
+_LIBCPP_CONSTEXPR pthread_mutex_t __os_mutex_init = PTHREAD_MUTEX_INITIALIZER; | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_mutex_lock(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_lock(__m); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_mutex_trylock(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_trylock(__m); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_mutex_unlock(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_unlock(__m); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_mutex_destroy(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_destroy(__m); | |
+} | |
+ | |
+// pthread hides differences between recursive and non-recursive mutexes | |
+// internally, other platform (e.g. Windows) might not, thus the following | |
+// is like the above except for init | |
+typedef pthread_mutex_t __os_recursive_mutex; | |
+ | |
+_LIBCPP_FUNC_VIS | |
+void __os_recursive_mutex_init(__os_mutex* __m); | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_recursive_mutex_lock(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_lock(__m); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_recursive_mutex_trylock(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_trylock(__m); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_recursive_mutex_unlock(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_unlock(__m); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_recursive_mutex_destroy(__os_mutex* __m) | |
+{ | |
+ return pthread_mutex_destroy(__m); | |
+} | |
+ | |
+_LIBCPP_FUNC_VIS void __os_call_once(volatile unsigned long&, void*, void(*)(void*)); | |
+ | |
+ | |
+} // namespace __libcpp_support | |
+ | |
+_LIBCPP_END_NAMESPACE_STD | |
+ | |
+#endif // _LIBCPP_SUPPORT_PTHREAD_MUTEX_H | |
+ | |
diff --git a/include/support/pthread/thread.h b/include/support/pthread/thread.h | |
new file mode 100644 | |
index 0000000..626344e | |
--- /dev/null | |
+++ b/include/support/pthread/thread.h | |
@@ -0,0 +1,121 @@ | |
+// -*- C++ -*- | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef _LIBCPP_SUPPORT_PTHREAD_THREAD_H | |
+#define _LIBCPP_SUPPORT_PTHREAD_THREAD_H | |
+ | |
+#ifndef _LIBCPP_INCLUDE_THREAD_API | |
+# error "This header can't be included directly" | |
+#endif // _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#include <pthread.h> | |
+#include <sched.h> | |
+ | |
+_LIBCPP_BEGIN_NAMESPACE_STD | |
+ | |
+namespace __libcpp_support | |
+{ | |
+ | |
+// thread local | |
+typedef pthread_key_t __os_tl_key; | |
+ | |
+template<class _Func> | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_tl_create(__os_tl_key* __key, _Func&& __at_exit) | |
+{ | |
+ return pthread_key_create(__key, __at_exit); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void __os_tl_destroy(__os_tl_key __key) | |
+{ | |
+ pthread_key_delete(__key); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void* __os_tl_get(__os_tl_key __key) | |
+{ | |
+ return pthread_getspecific(__key); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void __os_tl_set(__os_tl_key __key, void* __p) | |
+{ | |
+ pthread_setspecific(__key, __p); | |
+} | |
+ | |
+// thread id | |
+typedef pthread_t __os_thread_id; | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_thread_id_compare( __os_thread_id t1, __os_thread_id t2) | |
+{ | |
+ bool res = pthread_equal(t1, t2); | |
+ return res != 0 ? 0 : (t1 < t2 ? -1 : 1); | |
+} | |
+ | |
+template<class _CharT, class _Traits> | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+basic_ostream<_CharT, _Traits>& | |
+__os_write_to_ostream(basic_ostream<_CharT, _Traits>& __os, __os_thread_id __id) | |
+{ | |
+ return __os << __id; | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+__os_thread_id __os_get_current_thread_id() | |
+{ | |
+ return pthread_self(); | |
+} | |
+ | |
+ | |
+// thread | |
+typedef pthread_t __os_thread; | |
+_LIBCPP_CONSTEXPR pthread_t __os_thread_init = 0; | |
+ | |
+template<class _Func, class _Arg> | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_create_thread(__os_thread* __t, _Func&& __f, _Arg&& __arg) | |
+{ | |
+ return pthread_create(__t, 0, __f, __arg); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+__os_thread_id __os_get_thread_id(__os_thread __t) | |
+{ | |
+ return __t; | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_thread_join(__os_thread t) | |
+{ | |
+ return pthread_join(t, 0); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+int __os_thread_detach(__os_thread t) | |
+{ | |
+ return pthread_detach(t); | |
+} | |
+ | |
+inline _LIBCPP_INLINE_VISIBILITY | |
+void __os_yield() | |
+{ | |
+ sched_yield(); | |
+} | |
+ | |
+_LIBCPP_FUNC_VIS void __os_sleep_for(const chrono::nanoseconds& ns); | |
+ | |
+} // namespace __libcpp_support | |
+ | |
+_LIBCPP_END_NAMESPACE_STD | |
+ | |
+#endif // _LIBCPP_SUPPORT_PTHREAD_THREAD_H | |
+ | |
diff --git a/include/support/thread.h b/include/support/thread.h | |
new file mode 100644 | |
index 0000000..434c6f2 | |
--- /dev/null | |
+++ b/include/support/thread.h | |
@@ -0,0 +1,27 @@ | |
+// -*- C++ -*- | |
+//===----------------------------------------------------------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef _LIBCPP_SUPPORT_THREAD_H | |
+#define _LIBCPP_SUPPORT_THREAD_H | |
+ | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+ | |
+#define _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#if _LIBCPP_THREAD_API == _LIBCPP_PTHREAD | |
+# include <support/pthread/thread.h> | |
+#else | |
+# error "No thread API found" | |
+#endif // _LIBCPP_THREAD_API == _LIBCPP_PTHREAD | |
+#undef _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+ | |
+#endif // _LIBCPP_SUPPORT_THREAD_H | |
diff --git a/include/thread b/include/thread | |
index 8a30102..3aee773 100644 | |
--- a/include/thread | |
+++ b/include/thread | |
@@ -1,465 +1,470 @@ | |
// -*- C++ -*- | |
//===--------------------------- thread -----------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#ifndef _LIBCPP_THREAD | |
#define _LIBCPP_THREAD | |
/* | |
thread synopsis | |
#define __STDCPP_THREADS__ __cplusplus | |
namespace std | |
{ | |
class thread | |
{ | |
public: | |
class id; | |
typedef pthread_t native_handle_type; | |
thread() noexcept; | |
template <class F, class ...Args> explicit thread(F&& f, Args&&... args); | |
~thread(); | |
thread(const thread&) = delete; | |
thread(thread&& t) noexcept; | |
thread& operator=(const thread&) = delete; | |
thread& operator=(thread&& t) noexcept; | |
void swap(thread& t) noexcept; | |
bool joinable() const noexcept; | |
void join(); | |
void detach(); | |
id get_id() const noexcept; | |
native_handle_type native_handle(); | |
static unsigned hardware_concurrency() noexcept; | |
}; | |
void swap(thread& x, thread& y) noexcept; | |
class thread::id | |
{ | |
public: | |
id() noexcept; | |
}; | |
bool operator==(thread::id x, thread::id y) noexcept; | |
bool operator!=(thread::id x, thread::id y) noexcept; | |
bool operator< (thread::id x, thread::id y) noexcept; | |
bool operator<=(thread::id x, thread::id y) noexcept; | |
bool operator> (thread::id x, thread::id y) noexcept; | |
bool operator>=(thread::id x, thread::id y) noexcept; | |
template<class charT, class traits> | |
basic_ostream<charT, traits>& | |
operator<<(basic_ostream<charT, traits>& out, thread::id id); | |
namespace this_thread | |
{ | |
thread::id get_id() noexcept; | |
void yield() noexcept; | |
template <class Clock, class Duration> | |
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time); | |
template <class Rep, class Period> | |
void sleep_for(const chrono::duration<Rep, Period>& rel_time); | |
} // this_thread | |
} // std | |
*/ | |
#include <__config> | |
#include <iosfwd> | |
#include <__functional_base> | |
#include <type_traits> | |
#include <cstddef> | |
#include <functional> | |
#include <memory> | |
#include <system_error> | |
#include <chrono> | |
#include <__mutex_base> | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
#include <tuple> | |
#endif | |
-#include <pthread.h> | |
-#include <sched.h> | |
+#include <support/thread.h> | |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
#pragma GCC system_header | |
#endif | |
#define __STDCPP_THREADS__ __cplusplus | |
#ifdef _LIBCPP_HAS_NO_THREADS | |
#error <thread> is not supported on this single threaded system | |
#else // !_LIBCPP_HAS_NO_THREADS | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
template <class _Tp> | |
class __thread_specific_ptr | |
{ | |
- pthread_key_t __key_; | |
+ __libcpp_support::__os_tl_key __key_; | |
__thread_specific_ptr(const __thread_specific_ptr&); | |
__thread_specific_ptr& operator=(const __thread_specific_ptr&); | |
static void __at_thread_exit(void*); | |
public: | |
typedef _Tp* pointer; | |
__thread_specific_ptr(); | |
~__thread_specific_ptr(); | |
_LIBCPP_INLINE_VISIBILITY | |
- pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));} | |
+ pointer get() const {return static_cast<_Tp*>(__libcpp_support::__os_tl_get(__key_));} | |
_LIBCPP_INLINE_VISIBILITY | |
pointer operator*() const {return *get();} | |
_LIBCPP_INLINE_VISIBILITY | |
pointer operator->() const {return get();} | |
pointer release(); | |
void reset(pointer __p = nullptr); | |
}; | |
template <class _Tp> | |
void | |
__thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) | |
{ | |
delete static_cast<pointer>(__p); | |
} | |
template <class _Tp> | |
__thread_specific_ptr<_Tp>::__thread_specific_ptr() | |
{ | |
- int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit); | |
+ int __ec = __libcpp_support::__os_tl_create( | |
+ &__key_, | |
+ &__thread_specific_ptr::__at_thread_exit); | |
#ifndef _LIBCPP_NO_EXCEPTIONS | |
if (__ec) | |
throw system_error(error_code(__ec, system_category()), | |
"__thread_specific_ptr construction failed"); | |
#endif | |
} | |
template <class _Tp> | |
__thread_specific_ptr<_Tp>::~__thread_specific_ptr() | |
{ | |
- pthread_key_delete(__key_); | |
+ __libcpp_support::__os_tl_destroy(__key_); | |
} | |
template <class _Tp> | |
typename __thread_specific_ptr<_Tp>::pointer | |
__thread_specific_ptr<_Tp>::release() | |
{ | |
pointer __p = get(); | |
- pthread_setspecific(__key_, 0); | |
+ __libcpp_support::__os_tl_set(__key_, 0); | |
return __p; | |
} | |
template <class _Tp> | |
void | |
__thread_specific_ptr<_Tp>::reset(pointer __p) | |
{ | |
pointer __p_old = get(); | |
- pthread_setspecific(__key_, __p); | |
+ __libcpp_support::__os_tl_set(__key_, __p); | |
delete __p_old; | |
} | |
class _LIBCPP_TYPE_VIS thread; | |
class _LIBCPP_TYPE_VIS __thread_id; | |
namespace this_thread | |
{ | |
_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; | |
} // this_thread | |
template<> struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>; | |
class _LIBCPP_TYPE_VIS_ONLY __thread_id | |
{ | |
// FIXME: pthread_t is a pointer on Darwin but a long on Linux. | |
// NULL is the no-thread value on Darwin. Someone needs to check | |
// on other platforms. We assume 0 works everywhere for now. | |
- pthread_t __id_; | |
+ __libcpp_support::__os_thread_id __id_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
__thread_id() _NOEXCEPT : __id_(0) {} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT | |
- {return __x.__id_ == __y.__id_;} | |
+ {return __libcpp_support::__os_thread_id_compare(__x.__id_, __y.__id_) == 0;} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT | |
{return !(__x == __y);} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT | |
- {return __x.__id_ < __y.__id_;} | |
+ {return __libcpp_support::__os_thread_id_compare(__x.__id_, __y.__id_) < 0;} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT | |
{return !(__y < __x);} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT | |
{return __y < __x ;} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT | |
{return !(__x < __y);} | |
template<class _CharT, class _Traits> | |
friend | |
_LIBCPP_INLINE_VISIBILITY | |
basic_ostream<_CharT, _Traits>& | |
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) | |
- {return __os << __id.__id_;} | |
+ {return __libcpp_support::__os_write_to_ostream(__os, __id.__id_);} | |
private: | |
_LIBCPP_INLINE_VISIBILITY | |
- __thread_id(pthread_t __id) : __id_(__id) {} | |
+ __thread_id(__libcpp_support::__os_thread_id __id) : __id_(__id) {} | |
friend __thread_id this_thread::get_id() _NOEXCEPT; | |
friend class _LIBCPP_TYPE_VIS thread; | |
friend struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>; | |
}; | |
template<> | |
struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id> | |
: public unary_function<__thread_id, size_t> | |
{ | |
_LIBCPP_INLINE_VISIBILITY | |
size_t operator()(__thread_id __v) const | |
{ | |
- return hash<pthread_t>()(__v.__id_); | |
+ return hash<__libcpp_support::__os_thread_id>()(__v.__id_); | |
} | |
}; | |
namespace this_thread | |
{ | |
inline _LIBCPP_INLINE_VISIBILITY | |
__thread_id | |
get_id() _NOEXCEPT | |
{ | |
- return pthread_self(); | |
+ return __libcpp_support::__os_get_current_thread_id(); | |
} | |
} // this_thread | |
class _LIBCPP_TYPE_VIS thread | |
{ | |
- pthread_t __t_; | |
+ typedef __libcpp_support::__os_thread __thread_type; | |
+ __thread_type __t_; | |
thread(const thread&); | |
thread& operator=(const thread&); | |
public: | |
typedef __thread_id id; | |
- typedef pthread_t native_handle_type; | |
+ typedef __thread_type native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY | |
- thread() _NOEXCEPT : __t_(0) {} | |
+ thread() _NOEXCEPT : __t_(__libcpp_support::__os_thread_init) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fp, class ..._Args, | |
class = typename enable_if | |
< | |
!is_same<typename decay<_Fp>::type, thread>::value | |
>::type | |
> | |
explicit thread(_Fp&& __f, _Args&&... __args); | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fp> explicit thread(_Fp __f); | |
#endif | |
~thread(); | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
_LIBCPP_INLINE_VISIBILITY | |
thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = 0;} | |
thread& operator=(thread&& __t) _NOEXCEPT; | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
_LIBCPP_INLINE_VISIBILITY | |
void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} | |
_LIBCPP_INLINE_VISIBILITY | |
bool joinable() const _NOEXCEPT {return __t_ != 0;} | |
void join(); | |
void detach(); | |
_LIBCPP_INLINE_VISIBILITY | |
- id get_id() const _NOEXCEPT {return __t_;} | |
+ id get_id() const _NOEXCEPT {return __libcpp_support::__os_get_thread_id(__t_);} | |
_LIBCPP_INLINE_VISIBILITY | |
native_handle_type native_handle() _NOEXCEPT {return __t_;} | |
static unsigned hardware_concurrency() _NOEXCEPT; | |
}; | |
class __assoc_sub_state; | |
class _LIBCPP_HIDDEN __thread_struct_imp; | |
class _LIBCPP_TYPE_VIS __thread_struct | |
{ | |
__thread_struct_imp* __p_; | |
__thread_struct(const __thread_struct&); | |
__thread_struct& operator=(const __thread_struct&); | |
public: | |
__thread_struct(); | |
~__thread_struct(); | |
void notify_all_at_thread_exit(condition_variable*, mutex*); | |
void __make_ready_at_thread_exit(__assoc_sub_state*); | |
}; | |
_LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fp, class ..._Args, size_t ..._Indices> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>) | |
{ | |
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); | |
} | |
template <class _Fp> | |
void* | |
__thread_proxy(void* __vp) | |
{ | |
__thread_local_data().reset(new __thread_struct); | |
std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); | |
typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; | |
__thread_execute(*__p, _Index()); | |
return nullptr; | |
} | |
template <class _Fp, class ..._Args, | |
class | |
> | |
thread::thread(_Fp&& __f, _Args&&... __args) | |
{ | |
typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; | |
_VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)), | |
__decay_copy(_VSTD::forward<_Args>(__args))...)); | |
- int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get()); | |
+ int __ec = __libcpp_support::__os_create_thread(&__t_, &__thread_proxy<_Gp>, __p.get()); | |
if (__ec == 0) | |
__p.release(); | |
else | |
__throw_system_error(__ec, "thread constructor failed"); | |
} | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fp> | |
void* | |
__thread_proxy(void* __vp) | |
{ | |
__thread_local_data().reset(new __thread_struct); | |
std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); | |
(*__p)(); | |
return nullptr; | |
} | |
template <class _Fp> | |
thread::thread(_Fp __f) | |
{ | |
std::unique_ptr<_Fp> __p(new _Fp(__f)); | |
- int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get()); | |
+ int __ec = __libcpp_support::__os_create_thread(&__t_, &__thread_proxy<_Gp>, __p.get()); | |
if (__ec == 0) | |
__p.release(); | |
else | |
__throw_system_error(__ec, "thread constructor failed"); | |
} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
inline _LIBCPP_INLINE_VISIBILITY | |
thread& | |
thread::operator=(thread&& __t) _NOEXCEPT | |
{ | |
if (__t_ != 0) | |
terminate(); | |
__t_ = __t.__t_; | |
__t.__t_ = 0; | |
return *this; | |
} | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
inline _LIBCPP_INLINE_VISIBILITY | |
void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);} | |
namespace this_thread | |
{ | |
-_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns); | |
+inline _LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns) | |
+{ | |
+ __libcpp_support::__os_sleep_for(ns); | |
+} | |
template <class _Rep, class _Period> | |
void | |
sleep_for(const chrono::duration<_Rep, _Period>& __d) | |
{ | |
using namespace chrono; | |
if (__d > duration<_Rep, _Period>::zero()) | |
{ | |
_LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max(); | |
nanoseconds __ns; | |
if (__d < _Max) | |
{ | |
__ns = duration_cast<nanoseconds>(__d); | |
if (__ns < __d) | |
++__ns; | |
} | |
else | |
__ns = nanoseconds::max(); | |
sleep_for(__ns); | |
} | |
} | |
template <class _Clock, class _Duration> | |
void | |
sleep_until(const chrono::time_point<_Clock, _Duration>& __t) | |
{ | |
using namespace chrono; | |
mutex __mut; | |
condition_variable __cv; | |
unique_lock<mutex> __lk(__mut); | |
while (_Clock::now() < __t) | |
__cv.wait_until(__lk, __t); | |
} | |
template <class _Duration> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) | |
{ | |
using namespace chrono; | |
sleep_for(__t - steady_clock::now()); | |
} | |
inline _LIBCPP_INLINE_VISIBILITY | |
-void yield() _NOEXCEPT {sched_yield();} | |
+void yield() _NOEXCEPT {__libcpp_support::__os_yield();} | |
} // this_thread | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
#endif // _LIBCPP_THREAD | |
diff --git a/include/type_traits b/include/type_traits | |
index f0defaf..db8a043 100644 | |
--- a/include/type_traits | |
+++ b/include/type_traits | |
@@ -1,3773 +1,3773 @@ | |
// -*- C++ -*- | |
//===------------------------ type_traits ---------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#ifndef _LIBCPP_TYPE_TRAITS | |
#define _LIBCPP_TYPE_TRAITS | |
/* | |
type_traits synopsis | |
namespace std | |
{ | |
// helper class: | |
template <class T, T v> struct integral_constant; | |
typedef integral_constant<bool, true> true_type; // C++11 | |
typedef integral_constant<bool, false> false_type; // C++11 | |
template <bool B> // C++14 | |
using bool_constant = integral_constant<bool, B>; // C++14 | |
typedef bool_constant<true> true_type; // C++14 | |
typedef bool_constant<false> false_type; // C++14 | |
// helper traits | |
template <bool, class T = void> struct enable_if; | |
template <bool, class T, class F> struct conditional; | |
// Primary classification traits: | |
template <class T> struct is_void; | |
template <class T> struct is_null_pointer; // C++14 | |
template <class T> struct is_integral; | |
template <class T> struct is_floating_point; | |
template <class T> struct is_array; | |
template <class T> struct is_pointer; | |
template <class T> struct is_lvalue_reference; | |
template <class T> struct is_rvalue_reference; | |
template <class T> struct is_member_object_pointer; | |
template <class T> struct is_member_function_pointer; | |
template <class T> struct is_enum; | |
template <class T> struct is_union; | |
template <class T> struct is_class; | |
template <class T> struct is_function; | |
// Secondary classification traits: | |
template <class T> struct is_reference; | |
template <class T> struct is_arithmetic; | |
template <class T> struct is_fundamental; | |
template <class T> struct is_member_pointer; | |
template <class T> struct is_scalar; | |
template <class T> struct is_object; | |
template <class T> struct is_compound; | |
// Const-volatile properties and transformations: | |
template <class T> struct is_const; | |
template <class T> struct is_volatile; | |
template <class T> struct remove_const; | |
template <class T> struct remove_volatile; | |
template <class T> struct remove_cv; | |
template <class T> struct add_const; | |
template <class T> struct add_volatile; | |
template <class T> struct add_cv; | |
// Reference transformations: | |
template <class T> struct remove_reference; | |
template <class T> struct add_lvalue_reference; | |
template <class T> struct add_rvalue_reference; | |
// Pointer transformations: | |
template <class T> struct remove_pointer; | |
template <class T> struct add_pointer; | |
// Integral properties: | |
template <class T> struct is_signed; | |
template <class T> struct is_unsigned; | |
template <class T> struct make_signed; | |
template <class T> struct make_unsigned; | |
// Array properties and transformations: | |
template <class T> struct rank; | |
template <class T, unsigned I = 0> struct extent; | |
template <class T> struct remove_extent; | |
template <class T> struct remove_all_extents; | |
// Member introspection: | |
template <class T> struct is_pod; | |
template <class T> struct is_trivial; | |
template <class T> struct is_trivially_copyable; | |
template <class T> struct is_standard_layout; | |
template <class T> struct is_literal_type; | |
template <class T> struct is_empty; | |
template <class T> struct is_polymorphic; | |
template <class T> struct is_abstract; | |
template <class T> struct is_final; // C++14 | |
template <class T, class... Args> struct is_constructible; | |
template <class T> struct is_default_constructible; | |
template <class T> struct is_copy_constructible; | |
template <class T> struct is_move_constructible; | |
template <class T, class U> struct is_assignable; | |
template <class T> struct is_copy_assignable; | |
template <class T> struct is_move_assignable; | |
template <class T> struct is_destructible; | |
template <class T, class... Args> struct is_trivially_constructible; | |
template <class T> struct is_trivially_default_constructible; | |
template <class T> struct is_trivially_copy_constructible; | |
template <class T> struct is_trivially_move_constructible; | |
template <class T, class U> struct is_trivially_assignable; | |
template <class T> struct is_trivially_copy_assignable; | |
template <class T> struct is_trivially_move_assignable; | |
template <class T> struct is_trivially_destructible; | |
template <class T, class... Args> struct is_nothrow_constructible; | |
template <class T> struct is_nothrow_default_constructible; | |
template <class T> struct is_nothrow_copy_constructible; | |
template <class T> struct is_nothrow_move_constructible; | |
template <class T, class U> struct is_nothrow_assignable; | |
template <class T> struct is_nothrow_copy_assignable; | |
template <class T> struct is_nothrow_move_assignable; | |
template <class T> struct is_nothrow_destructible; | |
template <class T> struct has_virtual_destructor; | |
// Relationships between types: | |
template <class T, class U> struct is_same; | |
template <class Base, class Derived> struct is_base_of; | |
template <class From, class To> struct is_convertible; | |
// Alignment properties and transformations: | |
template <class T> struct alignment_of; | |
template <size_t Len, size_t Align = most_stringent_alignment_requirement> | |
struct aligned_storage; | |
template <size_t Len, class... Types> struct aligned_union; | |
template <class T> struct decay; | |
template <class... T> struct common_type; | |
template <class T> struct underlying_type; | |
template <class> class result_of; // undefined | |
template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>; | |
// const-volatile modifications: | |
template <class T> | |
using remove_const_t = typename remove_const<T>::type; // C++14 | |
template <class T> | |
using remove_volatile_t = typename remove_volatile<T>::type; // C++14 | |
template <class T> | |
using remove_cv_t = typename remove_cv<T>::type; // C++14 | |
template <class T> | |
using add_const_t = typename add_const<T>::type; // C++14 | |
template <class T> | |
using add_volatile_t = typename add_volatile<T>::type; // C++14 | |
template <class T> | |
using add_cv_t = typename add_cv<T>::type; // C++14 | |
// reference modifications: | |
template <class T> | |
using remove_reference_t = typename remove_reference<T>::type; // C++14 | |
template <class T> | |
using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; // C++14 | |
template <class T> | |
using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; // C++14 | |
// sign modifications: | |
template <class T> | |
using make_signed_t = typename make_signed<T>::type; // C++14 | |
template <class T> | |
using make_unsigned_t = typename make_unsigned<T>::type; // C++14 | |
// array modifications: | |
template <class T> | |
using remove_extent_t = typename remove_extent<T>::type; // C++14 | |
template <class T> | |
using remove_all_extents_t = typename remove_all_extents<T>::type; // C++14 | |
// pointer modifications: | |
template <class T> | |
using remove_pointer_t = typename remove_pointer<T>::type; // C++14 | |
template <class T> | |
using add_pointer_t = typename add_pointer<T>::type; // C++14 | |
// other transformations: | |
template <size_t Len, std::size_t Align=default-alignment> | |
using aligned_storage_t = typename aligned_storage<Len,Align>::type; // C++14 | |
template <std::size_t Len, class... Types> | |
using aligned_union_t = typename aligned_union<Len,Types...>::type; // C++14 | |
template <class T> | |
using decay_t = typename decay<T>::type; // C++14 | |
template <bool b, class T=void> | |
using enable_if_t = typename enable_if<b,T>::type; // C++14 | |
template <bool b, class T, class F> | |
using conditional_t = typename conditional<b,T,F>::type; // C++14 | |
template <class... T> | |
using common_type_t = typename common_type<T...>::type; // C++14 | |
template <class T> | |
using underlying_type_t = typename underlying_type<T>::type; // C++14 | |
template <class F, class... ArgTypes> | |
using result_of_t = typename result_of<F(ArgTypes...)>::type; // C++14 | |
template <class...> | |
using void_t = void; | |
} // C++17 | |
*/ | |
#include <__config> | |
#include <cstddef> | |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
#pragma GCC system_header | |
#endif | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
template <class> | |
struct __void_t { typedef void type; }; | |
-template <class _Tp> | |
-struct __identity { typedef _Tp type; }; | |
+template <class T> | |
+struct __identity { typedef T type; }; | |
template <class _Tp, bool> | |
struct _LIBCPP_TYPE_VIS_ONLY __dependent_type : public _Tp {}; | |
template <bool _Bp, class _If, class _Then> | |
struct _LIBCPP_TYPE_VIS_ONLY conditional {typedef _If type;}; | |
template <class _If, class _Then> | |
struct _LIBCPP_TYPE_VIS_ONLY conditional<false, _If, _Then> {typedef _Then type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type; | |
#endif | |
template <bool, class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if<true, _Tp> {typedef typename _Tp::type type;}; | |
template <bool, class _Tp = void> struct _LIBCPP_TYPE_VIS_ONLY enable_if {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY enable_if<true, _Tp> {typedef _Tp type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type; | |
#endif | |
struct __two {char __lx[2];}; | |
// helper class: | |
template <class _Tp, _Tp __v> | |
struct _LIBCPP_TYPE_VIS_ONLY integral_constant | |
{ | |
static _LIBCPP_CONSTEXPR const _Tp value = __v; | |
typedef _Tp value_type; | |
typedef integral_constant type; | |
_LIBCPP_INLINE_VISIBILITY | |
_LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;} | |
#if _LIBCPP_STD_VER > 11 | |
_LIBCPP_INLINE_VISIBILITY | |
constexpr value_type operator ()() const _NOEXCEPT {return value;} | |
#endif | |
}; | |
template <class _Tp, _Tp __v> | |
_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; | |
#if _LIBCPP_STD_VER > 14 | |
template <bool __b> | |
using bool_constant = integral_constant<bool, __b>; | |
#define _LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)> | |
#else | |
#define _LIBCPP_BOOL_CONSTANT(__b) integral_constant<bool,(__b)> | |
#endif | |
typedef _LIBCPP_BOOL_CONSTANT(true) true_type; | |
typedef _LIBCPP_BOOL_CONSTANT(false) false_type; | |
// is_const | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_const<_Tp const> : public true_type {}; | |
// is_volatile | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_volatile<_Tp volatile> : public true_type {}; | |
// remove_const | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_const<const _Tp> {typedef _Tp type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type; | |
#endif | |
// remove_volatile | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_volatile<volatile _Tp> {typedef _Tp type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type; | |
#endif | |
// remove_cv | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_cv | |
{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type; | |
#endif | |
// is_void | |
template <class _Tp> struct __libcpp_is_void : public false_type {}; | |
template <> struct __libcpp_is_void<void> : public true_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void | |
: public __libcpp_is_void<typename remove_cv<_Tp>::type> {}; | |
// __is_nullptr_t | |
template <class _Tp> struct __is_nullptr_t_impl : public false_type {}; | |
template <> struct __is_nullptr_t_impl<nullptr_t> : public true_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __is_nullptr_t | |
: public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_null_pointer | |
: public __is_nullptr_t_impl<typename remove_cv<_Tp>::type> {}; | |
#endif | |
// is_integral | |
template <class _Tp> struct __libcpp_is_integral : public false_type {}; | |
template <> struct __libcpp_is_integral<bool> : public true_type {}; | |
template <> struct __libcpp_is_integral<char> : public true_type {}; | |
template <> struct __libcpp_is_integral<signed char> : public true_type {}; | |
template <> struct __libcpp_is_integral<unsigned char> : public true_type {}; | |
template <> struct __libcpp_is_integral<wchar_t> : public true_type {}; | |
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS | |
template <> struct __libcpp_is_integral<char16_t> : public true_type {}; | |
template <> struct __libcpp_is_integral<char32_t> : public true_type {}; | |
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS | |
template <> struct __libcpp_is_integral<short> : public true_type {}; | |
template <> struct __libcpp_is_integral<unsigned short> : public true_type {}; | |
template <> struct __libcpp_is_integral<int> : public true_type {}; | |
template <> struct __libcpp_is_integral<unsigned int> : public true_type {}; | |
template <> struct __libcpp_is_integral<long> : public true_type {}; | |
template <> struct __libcpp_is_integral<unsigned long> : public true_type {}; | |
template <> struct __libcpp_is_integral<long long> : public true_type {}; | |
template <> struct __libcpp_is_integral<unsigned long long> : public true_type {}; | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
template <> struct __libcpp_is_integral<__int128_t> : public true_type {}; | |
template <> struct __libcpp_is_integral<__uint128_t> : public true_type {}; | |
#endif | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_integral | |
: public __libcpp_is_integral<typename remove_cv<_Tp>::type> {}; | |
// is_floating_point | |
template <class _Tp> struct __libcpp_is_floating_point : public false_type {}; | |
template <> struct __libcpp_is_floating_point<float> : public true_type {}; | |
template <> struct __libcpp_is_floating_point<double> : public true_type {}; | |
template <> struct __libcpp_is_floating_point<long double> : public true_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_floating_point | |
: public __libcpp_is_floating_point<typename remove_cv<_Tp>::type> {}; | |
// is_array | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array | |
: public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[]> | |
: public true_type {}; | |
template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY is_array<_Tp[_Np]> | |
: public true_type {}; | |
// is_pointer | |
template <class _Tp> struct __libcpp_is_pointer : public false_type {}; | |
template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pointer | |
: public __libcpp_is_pointer<typename remove_cv<_Tp>::type> {}; | |
// is_reference | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_lvalue_reference<_Tp&> : public true_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference : public false_type {}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_rvalue_reference<_Tp&&> : public true_type {}; | |
#endif | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&> : public true_type {}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_reference<_Tp&&> : public true_type {}; | |
#endif | |
// is_union | |
#if __has_feature(is_union) || (_GNUC_VER >= 403) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union | |
: public integral_constant<bool, __is_union(_Tp)> {}; | |
#else | |
template <class _Tp> struct __libcpp_union : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_union | |
: public __libcpp_union<typename remove_cv<_Tp>::type> {}; | |
#endif | |
// is_class | |
#if __has_feature(is_class) || (_GNUC_VER >= 403) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class | |
: public integral_constant<bool, __is_class(_Tp)> {}; | |
#else | |
namespace __is_class_imp | |
{ | |
template <class _Tp> char __test(int _Tp::*); | |
template <class _Tp> __two __test(...); | |
} | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class | |
: public integral_constant<bool, sizeof(__is_class_imp::__test<_Tp>(0)) == 1 && !is_union<_Tp>::value> {}; | |
#endif | |
// is_same | |
template <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS_ONLY is_same : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_same<_Tp, _Tp> : public true_type {}; | |
// is_function | |
namespace __libcpp_is_function_imp | |
{ | |
struct __dummy_type {}; | |
template <class _Tp> char __test(_Tp*); | |
template <class _Tp> char __test(__dummy_type); | |
template <class _Tp> __two __test(...); | |
template <class _Tp> _Tp& __source(int); | |
template <class _Tp> __dummy_type __source(...); | |
} | |
template <class _Tp, bool = is_class<_Tp>::value || | |
is_union<_Tp>::value || | |
is_void<_Tp>::value || | |
is_reference<_Tp>::value || | |
__is_nullptr_t<_Tp>::value > | |
struct __libcpp_is_function | |
: public integral_constant<bool, sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1> | |
{}; | |
template <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_function | |
: public __libcpp_is_function<_Tp> {}; | |
// is_member_function_pointer | |
// template <class _Tp> struct __libcpp_is_member_function_pointer : public false_type {}; | |
// template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {}; | |
// | |
template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> | |
struct __member_pointer_traits_imp | |
{ // forward declaration; specializations later | |
}; | |
template <class _Tp> struct __libcpp_is_member_function_pointer | |
: public false_type {}; | |
template <class _Ret, class _Class> | |
struct __libcpp_is_member_function_pointer<_Ret _Class::*> | |
: public is_function<_Ret> {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_function_pointer | |
: public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type>::type {}; | |
// is_member_pointer | |
template <class _Tp> struct __libcpp_is_member_pointer : public false_type {}; | |
template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> : public true_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_pointer | |
: public __libcpp_is_member_pointer<typename remove_cv<_Tp>::type> {}; | |
// is_member_object_pointer | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_member_object_pointer | |
: public integral_constant<bool, is_member_pointer<_Tp>::value && | |
!is_member_function_pointer<_Tp>::value> {}; | |
// is_enum | |
#if __has_feature(is_enum) || (_GNUC_VER >= 403) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum | |
: public integral_constant<bool, __is_enum(_Tp)> {}; | |
#else | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum | |
: public integral_constant<bool, !is_void<_Tp>::value && | |
!is_integral<_Tp>::value && | |
!is_floating_point<_Tp>::value && | |
!is_array<_Tp>::value && | |
!is_pointer<_Tp>::value && | |
!is_reference<_Tp>::value && | |
!is_member_pointer<_Tp>::value && | |
!is_union<_Tp>::value && | |
!is_class<_Tp>::value && | |
!is_function<_Tp>::value > {}; | |
#endif | |
// is_arithmetic | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_arithmetic | |
: public integral_constant<bool, is_integral<_Tp>::value || | |
is_floating_point<_Tp>::value> {}; | |
// is_fundamental | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_fundamental | |
: public integral_constant<bool, is_void<_Tp>::value || | |
__is_nullptr_t<_Tp>::value || | |
is_arithmetic<_Tp>::value> {}; | |
// is_scalar | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_scalar | |
: public integral_constant<bool, is_arithmetic<_Tp>::value || | |
is_member_pointer<_Tp>::value || | |
is_pointer<_Tp>::value || | |
__is_nullptr_t<_Tp>::value || | |
is_enum<_Tp>::value > {}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY is_scalar<nullptr_t> : public true_type {}; | |
// is_object | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_object | |
: public integral_constant<bool, is_scalar<_Tp>::value || | |
is_array<_Tp>::value || | |
is_union<_Tp>::value || | |
is_class<_Tp>::value > {}; | |
// is_compound | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_compound | |
: public integral_constant<bool, !is_fundamental<_Tp>::value> {}; | |
// add_const | |
template <class _Tp, bool = is_reference<_Tp>::value || | |
is_function<_Tp>::value || | |
is_const<_Tp>::value > | |
struct __add_const {typedef _Tp type;}; | |
template <class _Tp> | |
struct __add_const<_Tp, false> {typedef const _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_const | |
{typedef typename __add_const<_Tp>::type type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using add_const_t = typename add_const<_Tp>::type; | |
#endif | |
// add_volatile | |
template <class _Tp, bool = is_reference<_Tp>::value || | |
is_function<_Tp>::value || | |
is_volatile<_Tp>::value > | |
struct __add_volatile {typedef _Tp type;}; | |
template <class _Tp> | |
struct __add_volatile<_Tp, false> {typedef volatile _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_volatile | |
{typedef typename __add_volatile<_Tp>::type type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type; | |
#endif | |
// add_cv | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_cv | |
{typedef typename add_const<typename add_volatile<_Tp>::type>::type type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type; | |
#endif | |
// remove_reference | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&> {typedef _Tp type;}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&&> {typedef _Tp type;}; | |
#endif | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type; | |
#endif | |
// add_lvalue_reference | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference {typedef _Tp& type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<_Tp&> {typedef _Tp& type;}; // for older compiler | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<void> {typedef void type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const void> {typedef const void type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<volatile void> {typedef volatile void type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const volatile void> {typedef const volatile void type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; | |
#endif | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference {typedef _Tp&& type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<void> {typedef void type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const void> {typedef const void type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<volatile void> {typedef volatile void type;}; | |
template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const volatile void> {typedef const volatile void type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; | |
#endif | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
typename add_rvalue_reference<_Tp>::type | |
declval() _NOEXCEPT; | |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
typename add_lvalue_reference<_Tp>::type | |
declval(); | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
struct __any | |
{ | |
__any(...); | |
}; | |
// remove_pointer | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp*> {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const> {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* volatile> {typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_pointer<_Tp* const volatile> {typedef _Tp type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type; | |
#endif | |
// add_pointer | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer | |
{typedef typename remove_reference<_Tp>::type* type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type; | |
#endif | |
// is_signed | |
template <class _Tp, bool = is_integral<_Tp>::value> | |
struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {}; | |
template <class _Tp> | |
struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point | |
template <class _Tp, bool = is_arithmetic<_Tp>::value> | |
struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {}; | |
template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_signed : public __libcpp_is_signed<_Tp> {}; | |
// is_unsigned | |
template <class _Tp, bool = is_integral<_Tp>::value> | |
struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {}; | |
template <class _Tp> | |
struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point | |
template <class _Tp, bool = is_arithmetic<_Tp>::value> | |
struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {}; | |
template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_unsigned : public __libcpp_is_unsigned<_Tp> {}; | |
// rank | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank | |
: public integral_constant<size_t, 0> {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[]> | |
: public integral_constant<size_t, rank<_Tp>::value + 1> {}; | |
template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY rank<_Tp[_Np]> | |
: public integral_constant<size_t, rank<_Tp>::value + 1> {}; | |
// extent | |
template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TYPE_VIS_ONLY extent | |
: public integral_constant<size_t, 0> {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], 0> | |
: public integral_constant<size_t, 0> {}; | |
template <class _Tp, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[], _Ip> | |
: public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {}; | |
template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], 0> | |
: public integral_constant<size_t, _Np> {}; | |
template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TYPE_VIS_ONLY extent<_Tp[_Np], _Ip> | |
: public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {}; | |
// remove_extent | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent | |
{typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[]> | |
{typedef _Tp type;}; | |
template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_extent<_Tp[_Np]> | |
{typedef _Tp type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_extent_t = typename remove_extent<_Tp>::type; | |
#endif | |
// remove_all_extents | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents | |
{typedef _Tp type;}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[]> | |
{typedef typename remove_all_extents<_Tp>::type type;}; | |
template <class _Tp, size_t _Np> struct _LIBCPP_TYPE_VIS_ONLY remove_all_extents<_Tp[_Np]> | |
{typedef typename remove_all_extents<_Tp>::type type;}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type; | |
#endif | |
// decay | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY decay | |
{ | |
private: | |
typedef typename remove_reference<_Tp>::type _Up; | |
public: | |
typedef typename conditional | |
< | |
is_array<_Up>::value, | |
typename remove_extent<_Up>::type*, | |
typename conditional | |
< | |
is_function<_Up>::value, | |
typename add_pointer<_Up>::type, | |
typename remove_cv<_Up>::type | |
>::type | |
>::type type; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using decay_t = typename decay<_Tp>::type; | |
#endif | |
// is_abstract | |
namespace __is_abstract_imp | |
{ | |
template <class _Tp> char __test(_Tp (*)[1]); | |
template <class _Tp> __two __test(...); | |
} | |
template <class _Tp, bool = is_class<_Tp>::value> | |
struct __libcpp_abstract : public integral_constant<bool, sizeof(__is_abstract_imp::__test<_Tp>(0)) != 1> {}; | |
template <class _Tp> struct __libcpp_abstract<_Tp, false> : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_abstract : public __libcpp_abstract<_Tp> {}; | |
// is_final | |
#if defined(_LIBCPP_HAS_IS_FINAL) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY | |
__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {}; | |
#else | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY | |
__libcpp_is_final : public false_type {}; | |
#endif | |
#if defined(_LIBCPP_HAS_IS_FINAL) && _LIBCPP_STD_VER > 11 | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY | |
is_final : public integral_constant<bool, __is_final(_Tp)> {}; | |
#endif | |
// is_base_of | |
#ifdef _LIBCPP_HAS_IS_BASE_OF | |
template <class _Bp, class _Dp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_base_of | |
: public integral_constant<bool, __is_base_of(_Bp, _Dp)> {}; | |
#else // _LIBCPP_HAS_IS_BASE_OF | |
namespace __is_base_of_imp | |
{ | |
template <class _Tp> | |
struct _Dst | |
{ | |
_Dst(const volatile _Tp &); | |
}; | |
template <class _Tp> | |
struct _Src | |
{ | |
operator const volatile _Tp &(); | |
template <class _Up> operator const _Dst<_Up> &(); | |
}; | |
template <size_t> struct __one { typedef char type; }; | |
template <class _Bp, class _Dp> typename __one<sizeof(_Dst<_Bp>(declval<_Src<_Dp> >()))>::type __test(int); | |
template <class _Bp, class _Dp> __two __test(...); | |
} | |
template <class _Bp, class _Dp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_base_of | |
: public integral_constant<bool, is_class<_Bp>::value && | |
sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {}; | |
#endif // _LIBCPP_HAS_IS_BASE_OF | |
// is_convertible | |
#if __has_feature(is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) | |
template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible | |
: public integral_constant<bool, __is_convertible_to(_T1, _T2) && | |
!is_abstract<_T2>::value> {}; | |
#else // __has_feature(is_convertible_to) | |
namespace __is_convertible_imp | |
{ | |
template <class _Tp> void __test_convert(_Tp); | |
template <class _From, class _To, class = void> | |
struct __is_convertible_test : public false_type {}; | |
template <class _From, class _To> | |
struct __is_convertible_test<_From, _To, | |
decltype(__test_convert<_To>(_VSTD::declval<_From>()))> : public true_type | |
{}; | |
template <class _Tp> __two __test(...); | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> _Tp&& __source(); | |
#else | |
template <class _Tp> typename remove_reference<_Tp>::type& __source(); | |
#endif | |
template <class _Tp, bool _IsArray = is_array<_Tp>::value, | |
bool _IsFunction = is_function<_Tp>::value, | |
bool _IsVoid = is_void<_Tp>::value> | |
struct __is_array_function_or_void {enum {value = 0};}; | |
template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};}; | |
template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};}; | |
template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};}; | |
} | |
template <class _Tp, | |
unsigned = __is_convertible_imp::__is_array_function_or_void<typename remove_reference<_Tp>::type>::value> | |
struct __is_convertible_check | |
{ | |
static const size_t __v = 0; | |
}; | |
template <class _Tp> | |
struct __is_convertible_check<_Tp, 0> | |
{ | |
static const size_t __v = sizeof(_Tp); | |
}; | |
template <class _T1, class _T2, | |
unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value, | |
unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value> | |
struct __is_convertible | |
: public integral_constant<bool, | |
__is_convertible_imp::__is_convertible_test<_T1, _T2>::value | |
#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) | |
&& !(!is_function<_T1>::value && !is_reference<_T1>::value && is_reference<_T2>::value | |
&& (!is_const<typename remove_reference<_T2>::type>::value | |
|| is_volatile<typename remove_reference<_T2>::type>::value) | |
&& (is_same<typename remove_cv<_T1>::type, | |
typename remove_cv<typename remove_reference<_T2>::type>::type>::value | |
|| is_base_of<typename remove_reference<_T2>::type, _T1>::value)) | |
#endif | |
> | |
{}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 0> : false_type {}; | |
template <class _T1> struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {}; | |
template <class _T1> struct __is_convertible<const _T1, const _T1&, 1, 0> : true_type {}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _T1> struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {}; | |
template <class _T1> struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {}; | |
template <class _T1> struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {}; | |
template <class _T1> struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {}; | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2*, 1, 0> | |
: public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*>::value> {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const, 1, 0> | |
: public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const>::value> {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2* volatile, 1, 0> | |
: public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*volatile>::value> {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const volatile, 1, 0> | |
: public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const volatile>::value> {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 0> : public false_type {}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _T1> struct __is_convertible<_T1, _T1&&, 2, 0> : public true_type {}; | |
#endif | |
template <class _T1> struct __is_convertible<_T1, _T1&, 2, 0> : public true_type {}; | |
template <class _T1> struct __is_convertible<_T1, _T1*, 2, 0> : public true_type {}; | |
template <class _T1> struct __is_convertible<_T1, _T1*const, 2, 0> : public true_type {}; | |
template <class _T1> struct __is_convertible<_T1, _T1*volatile, 2, 0> : public true_type {}; | |
template <class _T1> struct __is_convertible<_T1, _T1*const volatile, 2, 0> : public true_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 0> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {}; | |
template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {}; | |
template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY is_convertible | |
: public __is_convertible<_T1, _T2> | |
{ | |
static const size_t __complete_check1 = __is_convertible_check<_T1>::__v; | |
static const size_t __complete_check2 = __is_convertible_check<_T2>::__v; | |
}; | |
#endif // __has_feature(is_convertible_to) | |
// is_empty | |
#if __has_feature(is_empty) || (_GNUC_VER >= 407) | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_empty | |
: public integral_constant<bool, __is_empty(_Tp)> {}; | |
#else // __has_feature(is_empty) | |
template <class _Tp> | |
struct __is_empty1 | |
: public _Tp | |
{ | |
double __lx; | |
}; | |
struct __is_empty2 | |
{ | |
double __lx; | |
}; | |
template <class _Tp, bool = is_class<_Tp>::value> | |
struct __libcpp_empty : public integral_constant<bool, sizeof(__is_empty1<_Tp>) == sizeof(__is_empty2)> {}; | |
template <class _Tp> struct __libcpp_empty<_Tp, false> : public false_type {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_empty : public __libcpp_empty<_Tp> {}; | |
#endif // __has_feature(is_empty) | |
// is_polymorphic | |
#if __has_feature(is_polymorphic) || defined(_LIBCPP_MSVC) | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic | |
: public integral_constant<bool, __is_polymorphic(_Tp)> {}; | |
#else | |
template<typename _Tp> char &__is_polymorphic_impl( | |
typename enable_if<sizeof((_Tp*)dynamic_cast<const volatile void*>(declval<_Tp*>())) != 0, | |
int>::type); | |
template<typename _Tp> __two &__is_polymorphic_impl(...); | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_polymorphic | |
: public integral_constant<bool, sizeof(__is_polymorphic_impl<_Tp>(0)) == 1> {}; | |
#endif // __has_feature(is_polymorphic) | |
// has_virtual_destructor | |
#if __has_feature(has_virtual_destructor) || (_GNUC_VER >= 403) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor | |
: public integral_constant<bool, __has_virtual_destructor(_Tp)> {}; | |
#else | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY has_virtual_destructor | |
: public false_type {}; | |
#endif | |
// alignment_of | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY alignment_of | |
: public integral_constant<size_t, __alignof__(_Tp)> {}; | |
// aligned_storage | |
template <class _Hp, class _Tp> | |
struct __type_list | |
{ | |
typedef _Hp _Head; | |
typedef _Tp _Tail; | |
}; | |
struct __nat | |
{ | |
#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS | |
__nat() = delete; | |
__nat(const __nat&) = delete; | |
__nat& operator=(const __nat&) = delete; | |
~__nat() = delete; | |
#endif | |
}; | |
template <class _Tp> | |
struct __align_type | |
{ | |
static const size_t value = alignment_of<_Tp>::value; | |
typedef _Tp type; | |
}; | |
struct __struct_double {long double __lx;}; | |
struct __struct_double4 {double __lx[4];}; | |
typedef | |
__type_list<__align_type<unsigned char>, | |
__type_list<__align_type<unsigned short>, | |
__type_list<__align_type<unsigned int>, | |
__type_list<__align_type<unsigned long>, | |
__type_list<__align_type<unsigned long long>, | |
__type_list<__align_type<double>, | |
__type_list<__align_type<long double>, | |
__type_list<__align_type<__struct_double>, | |
__type_list<__align_type<__struct_double4>, | |
__type_list<__align_type<int*>, | |
__nat | |
> > > > > > > > > > __all_types; | |
template <class _TL, size_t _Align> struct __find_pod; | |
template <class _Hp, size_t _Align> | |
struct __find_pod<__type_list<_Hp, __nat>, _Align> | |
{ | |
typedef typename conditional< | |
_Align == _Hp::value, | |
typename _Hp::type, | |
void | |
>::type type; | |
}; | |
template <class _Hp, class _Tp, size_t _Align> | |
struct __find_pod<__type_list<_Hp, _Tp>, _Align> | |
{ | |
typedef typename conditional< | |
_Align == _Hp::value, | |
typename _Hp::type, | |
typename __find_pod<_Tp, _Align>::type | |
>::type type; | |
}; | |
template <class _TL, size_t _Len> struct __find_max_align; | |
template <class _Hp, size_t _Len> | |
struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {}; | |
template <size_t _Len, size_t _A1, size_t _A2> | |
struct __select_align | |
{ | |
private: | |
static const size_t __min = _A2 < _A1 ? _A2 : _A1; | |
static const size_t __max = _A1 < _A2 ? _A2 : _A1; | |
public: | |
static const size_t value = _Len < __max ? __min : __max; | |
}; | |
template <class _Hp, class _Tp, size_t _Len> | |
struct __find_max_align<__type_list<_Hp, _Tp>, _Len> | |
: public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {}; | |
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> | |
struct _LIBCPP_TYPE_VIS_ONLY aligned_storage | |
{ | |
typedef typename __find_pod<__all_types, _Align>::type _Aligner; | |
static_assert(!is_void<_Aligner>::value, ""); | |
union type | |
{ | |
_Aligner __align; | |
unsigned char __data[_Len]; | |
}; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> | |
using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; | |
#endif | |
#define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \ | |
template <size_t _Len>\ | |
struct _LIBCPP_TYPE_VIS_ONLY aligned_storage<_Len, n>\ | |
{\ | |
struct _ALIGNAS(n) type\ | |
{\ | |
unsigned char __lx[_Len];\ | |
};\ | |
} | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000); | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000); | |
// MSDN says that MSVC does not support alignment beyond 8192 (=0x2000) | |
#if !defined(_LIBCPP_MSVC) | |
_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000); | |
#endif // !_LIBCPP_MSVC | |
#undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
// aligned_union | |
template <size_t _I0, size_t ..._In> | |
struct __static_max; | |
template <size_t _I0> | |
struct __static_max<_I0> | |
{ | |
static const size_t value = _I0; | |
}; | |
template <size_t _I0, size_t _I1, size_t ..._In> | |
struct __static_max<_I0, _I1, _In...> | |
{ | |
static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : | |
__static_max<_I1, _In...>::value; | |
}; | |
template <size_t _Len, class _Type0, class ..._Types> | |
struct aligned_union | |
{ | |
static const size_t alignment_value = __static_max<__alignof__(_Type0), | |
__alignof__(_Types)...>::value; | |
static const size_t __len = __static_max<_Len, sizeof(_Type0), | |
sizeof(_Types)...>::value; | |
typedef typename aligned_storage<__len, alignment_value>::type type; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <size_t _Len, class ..._Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type; | |
#endif | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Tp> | |
struct __numeric_type | |
{ | |
static void __test(...); | |
static float __test(float); | |
static double __test(char); | |
static double __test(int); | |
static double __test(unsigned); | |
static double __test(long); | |
static double __test(unsigned long); | |
static double __test(long long); | |
static double __test(unsigned long long); | |
static double __test(double); | |
static long double __test(long double); | |
typedef decltype(__test(declval<_Tp>())) type; | |
static const bool value = !is_same<type, void>::value; | |
}; | |
template <> | |
struct __numeric_type<void> | |
{ | |
static const bool value = true; | |
}; | |
// __promote | |
template <class _A1, class _A2 = void, class _A3 = void, | |
bool = __numeric_type<_A1>::value && | |
__numeric_type<_A2>::value && | |
__numeric_type<_A3>::value> | |
class __promote_imp | |
{ | |
public: | |
static const bool value = false; | |
}; | |
template <class _A1, class _A2, class _A3> | |
class __promote_imp<_A1, _A2, _A3, true> | |
{ | |
private: | |
typedef typename __promote_imp<_A1>::type __type1; | |
typedef typename __promote_imp<_A2>::type __type2; | |
typedef typename __promote_imp<_A3>::type __type3; | |
public: | |
typedef decltype(__type1() + __type2() + __type3()) type; | |
static const bool value = true; | |
}; | |
template <class _A1, class _A2> | |
class __promote_imp<_A1, _A2, void, true> | |
{ | |
private: | |
typedef typename __promote_imp<_A1>::type __type1; | |
typedef typename __promote_imp<_A2>::type __type2; | |
public: | |
typedef decltype(__type1() + __type2()) type; | |
static const bool value = true; | |
}; | |
template <class _A1> | |
class __promote_imp<_A1, void, void, true> | |
{ | |
public: | |
typedef typename __numeric_type<_A1>::type type; | |
static const bool value = true; | |
}; | |
template <class _A1, class _A2 = void, class _A3 = void> | |
class __promote : public __promote_imp<_A1, _A2, _A3> {}; | |
#ifdef _LIBCPP_STORE_AS_OPTIMIZATION | |
// __transform | |
template <class _Tp, size_t = sizeof(_Tp), bool = is_scalar<_Tp>::value> struct __transform {typedef _Tp type;}; | |
template <class _Tp> struct __transform<_Tp, 1, true> {typedef unsigned char type;}; | |
template <class _Tp> struct __transform<_Tp, 2, true> {typedef unsigned short type;}; | |
template <class _Tp> struct __transform<_Tp, 4, true> {typedef unsigned int type;}; | |
template <class _Tp> struct __transform<_Tp, 8, true> {typedef unsigned long long type;}; | |
#endif // _LIBCPP_STORE_AS_OPTIMIZATION | |
// make_signed / make_unsigned | |
typedef | |
__type_list<signed char, | |
__type_list<signed short, | |
__type_list<signed int, | |
__type_list<signed long, | |
__type_list<signed long long, | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
__type_list<__int128_t, | |
#endif | |
__nat | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
> | |
#endif | |
> > > > > __signed_types; | |
typedef | |
__type_list<unsigned char, | |
__type_list<unsigned short, | |
__type_list<unsigned int, | |
__type_list<unsigned long, | |
__type_list<unsigned long long, | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
__type_list<__uint128_t, | |
#endif | |
__nat | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
> | |
#endif | |
> > > > > __unsigned_types; | |
template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first; | |
template <class _Hp, class _Tp, size_t _Size> | |
struct __find_first<__type_list<_Hp, _Tp>, _Size, true> | |
{ | |
typedef _Hp type; | |
}; | |
template <class _Hp, class _Tp, size_t _Size> | |
struct __find_first<__type_list<_Hp, _Tp>, _Size, false> | |
{ | |
typedef typename __find_first<_Tp, _Size>::type type; | |
}; | |
template <class _Tp, class _Up, bool = is_const<typename remove_reference<_Tp>::type>::value, | |
bool = is_volatile<typename remove_reference<_Tp>::type>::value> | |
struct __apply_cv | |
{ | |
typedef _Up type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp, _Up, true, false> | |
{ | |
typedef const _Up type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp, _Up, false, true> | |
{ | |
typedef volatile _Up type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp, _Up, true, true> | |
{ | |
typedef const volatile _Up type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp&, _Up, false, false> | |
{ | |
typedef _Up& type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp&, _Up, true, false> | |
{ | |
typedef const _Up& type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp&, _Up, false, true> | |
{ | |
typedef volatile _Up& type; | |
}; | |
template <class _Tp, class _Up> | |
struct __apply_cv<_Tp&, _Up, true, true> | |
{ | |
typedef const volatile _Up& type; | |
}; | |
template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value> | |
struct __make_signed {}; | |
template <class _Tp> | |
struct __make_signed<_Tp, true> | |
{ | |
typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type; | |
}; | |
template <> struct __make_signed<bool, true> {}; | |
template <> struct __make_signed< signed short, true> {typedef short type;}; | |
template <> struct __make_signed<unsigned short, true> {typedef short type;}; | |
template <> struct __make_signed< signed int, true> {typedef int type;}; | |
template <> struct __make_signed<unsigned int, true> {typedef int type;}; | |
template <> struct __make_signed< signed long, true> {typedef long type;}; | |
template <> struct __make_signed<unsigned long, true> {typedef long type;}; | |
template <> struct __make_signed< signed long long, true> {typedef long long type;}; | |
template <> struct __make_signed<unsigned long long, true> {typedef long long type;}; | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
template <> struct __make_signed<__int128_t, true> {typedef __int128_t type;}; | |
template <> struct __make_signed<__uint128_t, true> {typedef __int128_t type;}; | |
#endif | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY make_signed | |
{ | |
typedef typename __apply_cv<_Tp, typename __make_signed<typename remove_cv<_Tp>::type>::type>::type type; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using make_signed_t = typename make_signed<_Tp>::type; | |
#endif | |
template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value> | |
struct __make_unsigned {}; | |
template <class _Tp> | |
struct __make_unsigned<_Tp, true> | |
{ | |
typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type; | |
}; | |
template <> struct __make_unsigned<bool, true> {}; | |
template <> struct __make_unsigned< signed short, true> {typedef unsigned short type;}; | |
template <> struct __make_unsigned<unsigned short, true> {typedef unsigned short type;}; | |
template <> struct __make_unsigned< signed int, true> {typedef unsigned int type;}; | |
template <> struct __make_unsigned<unsigned int, true> {typedef unsigned int type;}; | |
template <> struct __make_unsigned< signed long, true> {typedef unsigned long type;}; | |
template <> struct __make_unsigned<unsigned long, true> {typedef unsigned long type;}; | |
template <> struct __make_unsigned< signed long long, true> {typedef unsigned long long type;}; | |
template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;}; | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
template <> struct __make_unsigned<__int128_t, true> {typedef __uint128_t type;}; | |
template <> struct __make_unsigned<__uint128_t, true> {typedef __uint128_t type;}; | |
#endif | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY make_unsigned | |
{ | |
typedef typename __apply_cv<_Tp, typename __make_unsigned<typename remove_cv<_Tp>::type>::type>::type type; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type; | |
#endif | |
#ifdef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Tp, class _Up = void, class _Vp = void> | |
struct _LIBCPP_TYPE_VIS_ONLY common_type | |
{ | |
public: | |
typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp>::type type; | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, void, void> | |
{ | |
public: | |
typedef typename decay<_Tp>::type type; | |
}; | |
template <class _Tp, class _Up> | |
struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, void> | |
{ | |
private: | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
static _Tp&& __t(); | |
static _Up&& __u(); | |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
static _Tp __t(); | |
static _Up __u(); | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
public: | |
typedef typename remove_reference<decltype(true ? __t() : __u())>::type type; | |
}; | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template <class ..._Tp> struct common_type; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp> | |
{ | |
typedef typename decay<_Tp>::type type; | |
}; | |
template <class _Tp, class _Up> | |
struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up> | |
{ | |
private: | |
static _Tp&& __t(); | |
static _Up&& __u(); | |
static bool __f(); | |
public: | |
typedef typename decay<decltype(__f() ? __t() : __u())>::type type; | |
}; | |
template <class _Tp, class _Up, class ..._Vp> | |
struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up, _Vp...> | |
{ | |
typedef typename common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type; | |
#endif | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
// is_assignable | |
template<typename, typename _Tp> struct __select_2nd { typedef _Tp type; }; | |
template <class _Tp, class _Arg> | |
typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
__is_assignable_test(_Tp&&, _Arg&&); | |
#else | |
__is_assignable_test(_Tp, _Arg&); | |
#endif | |
template <class _Arg> | |
false_type | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
__is_assignable_test(__any, _Arg&&); | |
#else | |
__is_assignable_test(__any, _Arg&); | |
#endif | |
template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value> | |
struct __is_assignable_imp | |
: public common_type | |
< | |
decltype(_VSTD::__is_assignable_test(declval<_Tp>(), declval<_Arg>())) | |
>::type {}; | |
template <class _Tp, class _Arg> | |
struct __is_assignable_imp<_Tp, _Arg, true> | |
: public false_type | |
{ | |
}; | |
template <class _Tp, class _Arg> | |
struct is_assignable | |
: public __is_assignable_imp<_Tp, _Arg> {}; | |
// is_copy_assignable | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_copy_assignable | |
: public is_assignable<typename add_lvalue_reference<_Tp>::type, | |
typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {}; | |
// is_move_assignable | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_move_assignable | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
: public is_assignable<typename add_lvalue_reference<_Tp>::type, | |
const typename add_rvalue_reference<_Tp>::type> {}; | |
#else | |
: public is_copy_assignable<_Tp> {}; | |
#endif | |
// is_destructible | |
// if it's a reference, return true | |
// if it's a function, return false | |
// if it's void, return false | |
// if it's an array of unknown bound, return false | |
// Otherwise, return "std::declval<_Up&>().~_Up()" is well-formed | |
// where _Up is remove_all_extents<_Tp>::type | |
template <class> | |
struct __is_destructible_apply { typedef int type; }; | |
template <typename _Tp> | |
struct __is_destructor_wellformed { | |
template <typename _Tp1> | |
static char __test ( | |
typename __is_destructible_apply<decltype(_VSTD::declval<_Tp1&>().~_Tp1())>::type | |
); | |
template <typename _Tp1> | |
static __two __test (...); | |
static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char); | |
}; | |
template <class _Tp, bool> | |
struct __destructible_imp; | |
template <class _Tp> | |
struct __destructible_imp<_Tp, false> | |
: public _VSTD::integral_constant<bool, | |
__is_destructor_wellformed<typename _VSTD::remove_all_extents<_Tp>::type>::value> {}; | |
template <class _Tp> | |
struct __destructible_imp<_Tp, true> | |
: public _VSTD::true_type {}; | |
template <class _Tp, bool> | |
struct __destructible_false; | |
template <class _Tp> | |
struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, _VSTD::is_reference<_Tp>::value> {}; | |
template <class _Tp> | |
struct __destructible_false<_Tp, true> : public _VSTD::false_type {}; | |
template <class _Tp> | |
struct is_destructible | |
: public __destructible_false<_Tp, _VSTD::is_function<_Tp>::value> {}; | |
template <class _Tp> | |
struct is_destructible<_Tp[]> | |
: public _VSTD::false_type {}; | |
template <> | |
struct is_destructible<void> | |
: public _VSTD::false_type {}; | |
// move | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 | |
typename remove_reference<_Tp>::type&& | |
move(_Tp&& __t) _NOEXCEPT | |
{ | |
typedef typename remove_reference<_Tp>::type _Up; | |
return static_cast<_Up&&>(__t); | |
} | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 | |
_Tp&& | |
forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT | |
{ | |
return static_cast<_Tp&&>(__t); | |
} | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 | |
_Tp&& | |
forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT | |
{ | |
static_assert(!std::is_lvalue_reference<_Tp>::value, | |
"Can not forward an rvalue as an lvalue."); | |
return static_cast<_Tp&&>(__t); | |
} | |
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY | |
_Tp& | |
move(_Tp& __t) | |
{ | |
return __t; | |
} | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY | |
const _Tp& | |
move(const _Tp& __t) | |
{ | |
return __t; | |
} | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY | |
_Tp& | |
forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT | |
{ | |
return __t; | |
} | |
template <class _Tp> | |
class __rv | |
{ | |
typedef typename remove_reference<_Tp>::type _Trr; | |
_Trr& t_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
_Trr* operator->() {return &t_;} | |
_LIBCPP_INLINE_VISIBILITY | |
explicit __rv(_Trr& __t) : t_(__t) {} | |
}; | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY | |
typename decay<_Tp>::type | |
__decay_copy(_Tp&& __t) | |
{ | |
return _VSTD::forward<_Tp>(__t); | |
} | |
#else | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY | |
typename decay<_Tp>::type | |
__decay_copy(const _Tp& __t) | |
{ | |
return _VSTD::forward<_Tp>(__t); | |
} | |
#endif | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
#if __has_feature(cxx_reference_qualified_functions) || \ | |
(defined(_GNUC_VER) && _GNUC_VER >= 409) | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false> | |
{ | |
typedef _Class& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false> | |
{ | |
typedef _Class& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> | |
{ | |
typedef _Class const& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> | |
{ | |
typedef _Class const& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> | |
{ | |
typedef _Class volatile& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> | |
{ | |
typedef _Class volatile& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> | |
{ | |
typedef _Class const volatile& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> | |
{ | |
typedef _Class const volatile& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false> | |
{ | |
typedef _Class&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false> | |
{ | |
typedef _Class&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> | |
{ | |
typedef _Class const&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> | |
{ | |
typedef _Class const&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> | |
{ | |
typedef _Class volatile&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> | |
{ | |
typedef _Class volatile&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> | |
{ | |
typedef _Class const volatile&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param...); | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> | |
{ | |
typedef _Class const volatile&& _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_Param..., ...); | |
}; | |
#endif // __has_feature(cxx_reference_qualified_functions) || _GNUC_VER >= 409 | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(...), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (...); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...), true, false> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2, ...); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)() const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(...) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (...); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) const, true, false> | |
{ | |
typedef _Class const _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2, ...); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)() volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(...) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (...); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) volatile, true, false> | |
{ | |
typedef _Class volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2, ...); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)() const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (); | |
}; | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(...) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (...); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0); | |
}; | |
template <class _Rp, class _Class, class _P0> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, ...); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2); | |
}; | |
template <class _Rp, class _Class, class _P0, class _P1, class _P2> | |
struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) const volatile, true, false> | |
{ | |
typedef _Class const volatile _ClassType; | |
typedef _Rp _ReturnType; | |
typedef _Rp (_FnType) (_P0, _P1, _P2, ...); | |
}; | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Rp, class _Class> | |
struct __member_pointer_traits_imp<_Rp _Class::*, false, true> | |
{ | |
typedef _Class _ClassType; | |
typedef _Rp _ReturnType; | |
}; | |
template <class _MP> | |
struct __member_pointer_traits | |
: public __member_pointer_traits_imp<typename remove_cv<_MP>::type, | |
is_member_function_pointer<_MP>::value, | |
is_member_object_pointer<_MP>::value> | |
{ | |
// typedef ... _ClassType; | |
// typedef ... _ReturnType; | |
// typedef ... _FnType; | |
}; | |
// result_of | |
template <class _Callable> class result_of; | |
#ifdef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fn, bool, bool> | |
class __result_of | |
{ | |
}; | |
template <class _Fn> | |
class __result_of<_Fn(), true, false> | |
{ | |
public: | |
typedef decltype(declval<_Fn>()()) type; | |
}; | |
template <class _Fn, class _A0> | |
class __result_of<_Fn(_A0), true, false> | |
{ | |
public: | |
typedef decltype(declval<_Fn>()(declval<_A0>())) type; | |
}; | |
template <class _Fn, class _A0, class _A1> | |
class __result_of<_Fn(_A0, _A1), true, false> | |
{ | |
public: | |
typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>())) type; | |
}; | |
template <class _Fn, class _A0, class _A1, class _A2> | |
class __result_of<_Fn(_A0, _A1, _A2), true, false> | |
{ | |
public: | |
typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>(), declval<_A2>())) type; | |
}; | |
template <class _MP, class _Tp, bool _IsMemberFunctionPtr> | |
struct __result_of_mp; | |
// member function pointer | |
template <class _MP, class _Tp> | |
struct __result_of_mp<_MP, _Tp, true> | |
: public __identity<typename __member_pointer_traits<_MP>::_ReturnType> | |
{ | |
}; | |
// member data pointer | |
template <class _MP, class _Tp, bool> | |
struct __result_of_mdp; | |
template <class _Rp, class _Class, class _Tp> | |
struct __result_of_mdp<_Rp _Class::*, _Tp, false> | |
{ | |
typedef typename __apply_cv<decltype(*_VSTD::declval<_Tp>()), _Rp>::type& type; | |
}; | |
template <class _Rp, class _Class, class _Tp> | |
struct __result_of_mdp<_Rp _Class::*, _Tp, true> | |
{ | |
typedef typename __apply_cv<_Tp, _Rp>::type& type; | |
}; | |
template <class _Rp, class _Class, class _Tp> | |
struct __result_of_mp<_Rp _Class::*, _Tp, false> | |
: public __result_of_mdp<_Rp _Class::*, _Tp, | |
is_base_of<_Class, typename remove_reference<_Tp>::type>::value> | |
{ | |
}; | |
template <class _Fn, class _Tp> | |
class __result_of<_Fn(_Tp), false, true> // _Fn must be member pointer | |
: public __result_of_mp<typename remove_reference<_Fn>::type, | |
_Tp, | |
is_member_function_pointer<typename remove_reference<_Fn>::type>::value> | |
{ | |
}; | |
template <class _Fn, class _Tp, class _A0> | |
class __result_of<_Fn(_Tp, _A0), false, true> // _Fn must be member pointer | |
: public __result_of_mp<typename remove_reference<_Fn>::type, | |
_Tp, | |
is_member_function_pointer<typename remove_reference<_Fn>::type>::value> | |
{ | |
}; | |
template <class _Fn, class _Tp, class _A0, class _A1> | |
class __result_of<_Fn(_Tp, _A0, _A1), false, true> // _Fn must be member pointer | |
: public __result_of_mp<typename remove_reference<_Fn>::type, | |
_Tp, | |
is_member_function_pointer<typename remove_reference<_Fn>::type>::value> | |
{ | |
}; | |
template <class _Fn, class _Tp, class _A0, class _A1, class _A2> | |
class __result_of<_Fn(_Tp, _A0, _A1, _A2), false, true> // _Fn must be member pointer | |
: public __result_of_mp<typename remove_reference<_Fn>::type, | |
_Tp, | |
is_member_function_pointer<typename remove_reference<_Fn>::type>::value> | |
{ | |
}; | |
// result_of | |
template <class _Fn> | |
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn()> | |
: public __result_of<_Fn(), | |
is_class<typename remove_reference<_Fn>::type>::value || | |
is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value, | |
is_member_pointer<typename remove_reference<_Fn>::type>::value | |
> | |
{ | |
}; | |
template <class _Fn, class _A0> | |
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0)> | |
: public __result_of<_Fn(_A0), | |
is_class<typename remove_reference<_Fn>::type>::value || | |
is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value, | |
is_member_pointer<typename remove_reference<_Fn>::type>::value | |
> | |
{ | |
}; | |
template <class _Fn, class _A0, class _A1> | |
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1)> | |
: public __result_of<_Fn(_A0, _A1), | |
is_class<typename remove_reference<_Fn>::type>::value || | |
is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value, | |
is_member_pointer<typename remove_reference<_Fn>::type>::value | |
> | |
{ | |
}; | |
template <class _Fn, class _A0, class _A1, class _A2> | |
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)> | |
: public __result_of<_Fn(_A0, _A1, _A2), | |
is_class<typename remove_reference<_Fn>::type>::value || | |
is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value, | |
is_member_pointer<typename remove_reference<_Fn>::type>::value | |
> | |
{ | |
}; | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
// template <class T, class... Args> struct is_constructible; | |
namespace __is_construct | |
{ | |
struct __nat {}; | |
} | |
#if __has_feature(is_constructible) | |
template <class _Tp, class ..._Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_constructible | |
: public integral_constant<bool, __is_constructible(_Tp, _Args...)> | |
{}; | |
#else | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
// main is_constructible test | |
template <class _Tp, class ..._Args> | |
typename __select_2nd<decltype(_VSTD::move(_Tp(_VSTD::declval<_Args>()...))), true_type>::type | |
__is_constructible_test(_Tp&&, _Args&& ...); | |
template <class ..._Args> | |
false_type | |
__is_constructible_test(__any, _Args&& ...); | |
template <bool, class _Tp, class... _Args> | |
struct __libcpp_is_constructible // false, _Tp is not a scalar | |
: public common_type | |
< | |
decltype(__is_constructible_test(declval<_Tp>(), declval<_Args>()...)) | |
>::type | |
{}; | |
// function types are not constructible | |
template <class _Rp, class... _A1, class... _A2> | |
struct __libcpp_is_constructible<false, _Rp(_A1...), _A2...> | |
: public false_type | |
{}; | |
// handle scalars and reference types | |
// Scalars are default constructible, references are not | |
template <class _Tp> | |
struct __libcpp_is_constructible<true, _Tp> | |
: public is_scalar<_Tp> | |
{}; | |
// Scalars and references are constructible from one arg if that arg is | |
// implicitly convertible to the scalar or reference. | |
template <class _Tp> | |
struct __is_constructible_ref | |
{ | |
true_type static __lxx(_Tp); | |
false_type static __lxx(...); | |
}; | |
template <class _Tp, class _A0> | |
struct __libcpp_is_constructible<true, _Tp, _A0> | |
: public common_type | |
< | |
decltype(__is_constructible_ref<_Tp>::__lxx(declval<_A0>())) | |
>::type | |
{}; | |
// Scalars and references are not constructible from multiple args. | |
template <class _Tp, class _A0, class ..._Args> | |
struct __libcpp_is_constructible<true, _Tp, _A0, _Args...> | |
: public false_type | |
{}; | |
// Treat scalars and reference types separately | |
template <bool, class _Tp, class... _Args> | |
struct __is_constructible_void_check | |
: public __libcpp_is_constructible<is_scalar<_Tp>::value || is_reference<_Tp>::value, | |
_Tp, _Args...> | |
{}; | |
// If any of T or Args is void, is_constructible should be false | |
template <class _Tp, class... _Args> | |
struct __is_constructible_void_check<true, _Tp, _Args...> | |
: public false_type | |
{}; | |
template <class ..._Args> struct __contains_void; | |
template <> struct __contains_void<> : false_type {}; | |
template <class _A0, class ..._Args> | |
struct __contains_void<_A0, _Args...> | |
{ | |
static const bool value = is_void<_A0>::value || | |
__contains_void<_Args...>::value; | |
}; | |
// is_constructible entry point | |
template <class _Tp, class... _Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_constructible | |
: public __is_constructible_void_check<__contains_void<_Tp, _Args...>::value | |
|| is_abstract<_Tp>::value, | |
_Tp, _Args...> | |
{}; | |
// Array types are default constructible if their element type | |
// is default constructible | |
template <class _Ap, size_t _Np> | |
struct __libcpp_is_constructible<false, _Ap[_Np]> | |
: public is_constructible<typename remove_all_extents<_Ap>::type> | |
{}; | |
// Otherwise array types are not constructible by this syntax | |
template <class _Ap, size_t _Np, class ..._Args> | |
struct __libcpp_is_constructible<false, _Ap[_Np], _Args...> | |
: public false_type | |
{}; | |
// Incomplete array types are not constructible | |
template <class _Ap, class ..._Args> | |
struct __libcpp_is_constructible<false, _Ap[], _Args...> | |
: public false_type | |
{}; | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
// template <class T> struct is_constructible0; | |
// main is_constructible0 test | |
template <class _Tp> | |
decltype((_Tp(), true_type())) | |
__is_constructible0_test(_Tp&); | |
false_type | |
__is_constructible0_test(__any); | |
template <class _Tp, class _A0> | |
decltype((_Tp(_VSTD::declval<_A0>()), true_type())) | |
__is_constructible1_test(_Tp&, _A0&); | |
template <class _A0> | |
false_type | |
__is_constructible1_test(__any, _A0&); | |
template <class _Tp, class _A0, class _A1> | |
decltype((_Tp(_VSTD::declval<_A0>(), _VSTD::declval<_A1>()), true_type())) | |
__is_constructible2_test(_Tp&, _A0&, _A1&); | |
template <class _A0, class _A1> | |
false_type | |
__is_constructible2_test(__any, _A0&, _A1&); | |
template <bool, class _Tp> | |
struct __is_constructible0_imp // false, _Tp is not a scalar | |
: public common_type | |
< | |
decltype(__is_constructible0_test(declval<_Tp&>())) | |
>::type | |
{}; | |
template <bool, class _Tp, class _A0> | |
struct __is_constructible1_imp // false, _Tp is not a scalar | |
: public common_type | |
< | |
decltype(__is_constructible1_test(declval<_Tp&>(), declval<_A0&>())) | |
>::type | |
{}; | |
template <bool, class _Tp, class _A0, class _A1> | |
struct __is_constructible2_imp // false, _Tp is not a scalar | |
: public common_type | |
< | |
decltype(__is_constructible2_test(declval<_Tp&>(), declval<_A0>(), declval<_A1>())) | |
>::type | |
{}; | |
// handle scalars and reference types | |
// Scalars are default constructible, references are not | |
template <class _Tp> | |
struct __is_constructible0_imp<true, _Tp> | |
: public is_scalar<_Tp> | |
{}; | |
template <class _Tp, class _A0> | |
struct __is_constructible1_imp<true, _Tp, _A0> | |
: public is_convertible<_A0, _Tp> | |
{}; | |
template <class _Tp, class _A0, class _A1> | |
struct __is_constructible2_imp<true, _Tp, _A0, _A1> | |
: public false_type | |
{}; | |
// Treat scalars and reference types separately | |
template <bool, class _Tp> | |
struct __is_constructible0_void_check | |
: public __is_constructible0_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value, | |
_Tp> | |
{}; | |
template <bool, class _Tp, class _A0> | |
struct __is_constructible1_void_check | |
: public __is_constructible1_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value, | |
_Tp, _A0> | |
{}; | |
template <bool, class _Tp, class _A0, class _A1> | |
struct __is_constructible2_void_check | |
: public __is_constructible2_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value, | |
_Tp, _A0, _A1> | |
{}; | |
// If any of T or Args is void, is_constructible should be false | |
template <class _Tp> | |
struct __is_constructible0_void_check<true, _Tp> | |
: public false_type | |
{}; | |
template <class _Tp, class _A0> | |
struct __is_constructible1_void_check<true, _Tp, _A0> | |
: public false_type | |
{}; | |
template <class _Tp, class _A0, class _A1> | |
struct __is_constructible2_void_check<true, _Tp, _A0, _A1> | |
: public false_type | |
{}; | |
// is_constructible entry point | |
template <class _Tp, class _A0 = __is_construct::__nat, | |
class _A1 = __is_construct::__nat> | |
struct _LIBCPP_TYPE_VIS_ONLY is_constructible | |
: public __is_constructible2_void_check<is_void<_Tp>::value | |
|| is_abstract<_Tp>::value | |
|| is_function<_Tp>::value | |
|| is_void<_A0>::value | |
|| is_void<_A1>::value, | |
_Tp, _A0, _A1> | |
{}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, __is_construct::__nat, __is_construct::__nat> | |
: public __is_constructible0_void_check<is_void<_Tp>::value | |
|| is_abstract<_Tp>::value | |
|| is_function<_Tp>::value, | |
_Tp> | |
{}; | |
template <class _Tp, class _A0> | |
struct _LIBCPP_TYPE_VIS_ONLY is_constructible<_Tp, _A0, __is_construct::__nat> | |
: public __is_constructible1_void_check<is_void<_Tp>::value | |
|| is_abstract<_Tp>::value | |
|| is_function<_Tp>::value | |
|| is_void<_A0>::value, | |
_Tp, _A0> | |
{}; | |
// Array types are default constructible if their element type | |
// is default constructible | |
template <class _Ap, size_t _Np> | |
struct __is_constructible0_imp<false, _Ap[_Np]> | |
: public is_constructible<typename remove_all_extents<_Ap>::type> | |
{}; | |
template <class _Ap, size_t _Np, class _A0> | |
struct __is_constructible1_imp<false, _Ap[_Np], _A0> | |
: public false_type | |
{}; | |
template <class _Ap, size_t _Np, class _A0, class _A1> | |
struct __is_constructible2_imp<false, _Ap[_Np], _A0, _A1> | |
: public false_type | |
{}; | |
// Incomplete array types are not constructible | |
template <class _Ap> | |
struct __is_constructible0_imp<false, _Ap[]> | |
: public false_type | |
{}; | |
template <class _Ap, class _A0> | |
struct __is_constructible1_imp<false, _Ap[], _A0> | |
: public false_type | |
{}; | |
template <class _Ap, class _A0, class _A1> | |
struct __is_constructible2_imp<false, _Ap[], _A0, _A1> | |
: public false_type | |
{}; | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
#endif // __has_feature(is_constructible) | |
// is_default_constructible | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_default_constructible | |
: public is_constructible<_Tp> | |
{}; | |
// is_copy_constructible | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_copy_constructible | |
: public is_constructible<_Tp, | |
typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {}; | |
// is_move_constructible | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_move_constructible | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
: public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> | |
#else | |
: public is_copy_constructible<_Tp> | |
#endif | |
{}; | |
// is_trivially_constructible | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501 | |
template <class _Tp, class... _Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible | |
: integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)> | |
{ | |
}; | |
#else // !__has_feature(is_trivially_constructible) | |
template <class _Tp, class... _Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible | |
: false_type | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp> | |
#if __has_feature(has_trivial_constructor) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_trivial_constructor(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&&> | |
#else | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp> | |
#endif | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&> | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&> | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
#endif // !__has_feature(is_trivially_constructible) | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Tp, class _A0 = __is_construct::__nat, | |
class _A1 = __is_construct::__nat> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible | |
: false_type | |
{ | |
}; | |
#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501 | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat, | |
__is_construct::__nat> | |
: integral_constant<bool, __is_trivially_constructible(_Tp)> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp, | |
__is_construct::__nat> | |
: integral_constant<bool, __is_trivially_constructible(_Tp, _Tp)> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&, | |
__is_construct::__nat> | |
: integral_constant<bool, __is_trivially_constructible(_Tp, const _Tp&)> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&, | |
__is_construct::__nat> | |
: integral_constant<bool, __is_trivially_constructible(_Tp, _Tp&)> | |
{ | |
}; | |
#else // !__has_feature(is_trivially_constructible) | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat, | |
__is_construct::__nat> | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp, | |
__is_construct::__nat> | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, const _Tp&, | |
__is_construct::__nat> | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, _Tp&, | |
__is_construct::__nat> | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
{ | |
}; | |
#endif // !__has_feature(is_trivially_constructible) | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
// is_trivially_default_constructible | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_default_constructible | |
: public is_trivially_constructible<_Tp> | |
{}; | |
// is_trivially_copy_constructible | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_constructible | |
: public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type> | |
{}; | |
// is_trivially_move_constructible | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_constructible | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
: public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> | |
#else | |
: public is_trivially_copy_constructible<_Tp> | |
#endif | |
{}; | |
// is_trivially_assignable | |
#if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501 | |
template <class _Tp, class _Arg> | |
struct is_trivially_assignable | |
: integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> | |
{ | |
}; | |
#else // !__has_feature(is_trivially_assignable) | |
template <class _Tp, class _Arg> | |
struct is_trivially_assignable | |
: public false_type {}; | |
template <class _Tp> | |
struct is_trivially_assignable<_Tp&, _Tp> | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
template <class _Tp> | |
struct is_trivially_assignable<_Tp&, _Tp&> | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
template <class _Tp> | |
struct is_trivially_assignable<_Tp&, const _Tp&> | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
struct is_trivially_assignable<_Tp&, _Tp&&> | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#endif // !__has_feature(is_trivially_assignable) | |
// is_trivially_copy_assignable | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_assignable | |
: public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type, | |
typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {}; | |
// is_trivially_move_assignable | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_move_assignable | |
: public is_trivially_assignable<typename add_lvalue_reference<_Tp>::type, | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
typename add_rvalue_reference<_Tp>::type> | |
#else | |
typename add_lvalue_reference<_Tp>::type> | |
#endif | |
{}; | |
// is_trivially_destructible | |
#if __has_feature(has_trivial_destructor) || (_GNUC_VER >= 403) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible | |
: public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {}; | |
#else | |
template <class _Tp> struct __libcpp_trivial_destructor | |
: public integral_constant<bool, is_scalar<_Tp>::value || | |
is_reference<_Tp>::value> {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible | |
: public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible<_Tp[]> | |
: public false_type {}; | |
#endif | |
// is_nothrow_constructible | |
#if 0 | |
template <class _Tp, class... _Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible | |
: public integral_constant<bool, __is_nothrow_constructible(_Tp(_Args...))> | |
{ | |
}; | |
#else | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) | |
template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible; | |
template <class _Tp, class... _Args> | |
struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...> | |
: public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> | |
{ | |
}; | |
template <class _Tp> | |
void __implicit_conversion_to(_Tp) noexcept { } | |
template <class _Tp, class _Arg> | |
struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg> | |
: public integral_constant<bool, noexcept(__implicit_conversion_to<_Tp>(declval<_Arg>()))> | |
{ | |
}; | |
template <class _Tp, bool _IsReference, class... _Args> | |
struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...> | |
: public false_type | |
{ | |
}; | |
template <class _Tp, class... _Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible | |
: __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...> | |
{ | |
}; | |
template <class _Tp, size_t _Ns> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp[_Ns]> | |
: __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> | |
{ | |
}; | |
#else // __has_feature(cxx_noexcept) | |
template <class _Tp, class... _Args> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible | |
: false_type | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp> | |
#if __has_feature(has_nothrow_constructor) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_constructor(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&&> | |
#else | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp> | |
#endif | |
#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_copy(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&> | |
#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_copy(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&> | |
#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_copy(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
#endif // __has_feature(cxx_noexcept) | |
#else // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Tp, class _A0 = __is_construct::__nat, | |
class _A1 = __is_construct::__nat> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible | |
: false_type | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, __is_construct::__nat, | |
__is_construct::__nat> | |
#if __has_feature(has_nothrow_constructor) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_constructor(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp, | |
__is_construct::__nat> | |
#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_copy(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, const _Tp&, | |
__is_construct::__nat> | |
#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_copy(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_constructible<_Tp, _Tp&, | |
__is_construct::__nat> | |
#if __has_feature(has_nothrow_copy) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_copy(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> | |
#endif | |
{ | |
}; | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
#endif // __has_feature(is_nothrow_constructible) | |
// is_nothrow_default_constructible | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_default_constructible | |
: public is_nothrow_constructible<_Tp> | |
{}; | |
// is_nothrow_copy_constructible | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_constructible | |
: public is_nothrow_constructible<_Tp, | |
typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {}; | |
// is_nothrow_move_constructible | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_constructible | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
: public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> | |
#else | |
: public is_nothrow_copy_constructible<_Tp> | |
#endif | |
{}; | |
// is_nothrow_assignable | |
#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) | |
template <bool, class _Tp, class _Arg> struct __libcpp_is_nothrow_assignable; | |
template <class _Tp, class _Arg> | |
struct __libcpp_is_nothrow_assignable<false, _Tp, _Arg> | |
: public false_type | |
{ | |
}; | |
template <class _Tp, class _Arg> | |
struct __libcpp_is_nothrow_assignable<true, _Tp, _Arg> | |
: public integral_constant<bool, noexcept(_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>()) > | |
{ | |
}; | |
template <class _Tp, class _Arg> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable | |
: public __libcpp_is_nothrow_assignable<is_assignable<_Tp, _Arg>::value, _Tp, _Arg> | |
{ | |
}; | |
#else // __has_feature(cxx_noexcept) | |
template <class _Tp, class _Arg> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable | |
: public false_type {}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp> | |
#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_assign(_Tp)> {}; | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
#endif | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, _Tp&> | |
#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_assign(_Tp)> {}; | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
#endif | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_assignable<_Tp&, const _Tp&> | |
#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_assign(_Tp)> {}; | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
#endif | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
struct is_nothrow_assignable<_Tp&, _Tp&&> | |
#if __has_feature(has_nothrow_assign) || (_GNUC_VER >= 403) | |
: integral_constant<bool, __has_nothrow_assign(_Tp)> {}; | |
#else | |
: integral_constant<bool, is_scalar<_Tp>::value> {}; | |
#endif | |
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
#endif // __has_feature(cxx_noexcept) | |
// is_nothrow_copy_assignable | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_copy_assignable | |
: public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type, | |
typename add_lvalue_reference<typename add_const<_Tp>::type>::type> {}; | |
// is_nothrow_move_assignable | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_move_assignable | |
: public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type, | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
typename add_rvalue_reference<_Tp>::type> | |
#else | |
typename add_lvalue_reference<_Tp>::type> | |
#endif | |
{}; | |
// is_nothrow_destructible | |
#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) | |
template <bool, class _Tp> struct __libcpp_is_nothrow_destructible; | |
template <class _Tp> | |
struct __libcpp_is_nothrow_destructible<false, _Tp> | |
: public false_type | |
{ | |
}; | |
template <class _Tp> | |
struct __libcpp_is_nothrow_destructible<true, _Tp> | |
: public integral_constant<bool, noexcept(_VSTD::declval<_Tp>().~_Tp()) > | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible | |
: public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp> | |
{ | |
}; | |
template <class _Tp, size_t _Ns> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[_Ns]> | |
: public is_nothrow_destructible<_Tp> | |
{ | |
}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&> | |
: public true_type | |
{ | |
}; | |
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp&&> | |
: public true_type | |
{ | |
}; | |
#endif | |
#else | |
template <class _Tp> struct __libcpp_nothrow_destructor | |
: public integral_constant<bool, is_scalar<_Tp>::value || | |
is_reference<_Tp>::value> {}; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible | |
: public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {}; | |
template <class _Tp> | |
struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[]> | |
: public false_type {}; | |
#endif | |
// is_pod | |
#if __has_feature(is_pod) || (_GNUC_VER >= 403) | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod | |
: public integral_constant<bool, __is_pod(_Tp)> {}; | |
#else | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_pod | |
: public integral_constant<bool, is_trivially_default_constructible<_Tp>::value && | |
is_trivially_copy_constructible<_Tp>::value && | |
is_trivially_copy_assignable<_Tp>::value && | |
is_trivially_destructible<_Tp>::value> {}; | |
#endif | |
// is_literal_type; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_literal_type | |
#ifdef _LIBCPP_IS_LITERAL | |
: public integral_constant<bool, _LIBCPP_IS_LITERAL(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value || | |
is_reference<typename remove_all_extents<_Tp>::type>::value> | |
#endif | |
{}; | |
// is_standard_layout; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_standard_layout | |
#if __has_feature(is_standard_layout) || (_GNUC_VER >= 407) | |
: public integral_constant<bool, __is_standard_layout(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value> | |
#endif | |
{}; | |
// is_trivially_copyable; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copyable | |
#if __has_feature(is_trivially_copyable) | |
: public integral_constant<bool, __is_trivially_copyable(_Tp)> | |
#elif _GNUC_VER >= 501 | |
: public integral_constant<bool, !is_volatile<_Tp>::value && __is_trivially_copyable(_Tp)> | |
#else | |
: integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value> | |
#endif | |
{}; | |
// is_trivial; | |
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivial | |
#if __has_feature(is_trivial) || _GNUC_VER >= 407 | |
: public integral_constant<bool, __is_trivial(_Tp)> | |
#else | |
: integral_constant<bool, is_trivially_copyable<_Tp>::value && | |
is_trivially_default_constructible<_Tp>::value> | |
#endif | |
{}; | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
// Check for complete types | |
template <class ..._Tp> struct __check_complete; | |
template <> | |
struct __check_complete<> | |
{ | |
}; | |
template <class _Hp, class _T0, class ..._Tp> | |
struct __check_complete<_Hp, _T0, _Tp...> | |
: private __check_complete<_Hp>, | |
private __check_complete<_T0, _Tp...> | |
{ | |
}; | |
template <class _Hp> | |
struct __check_complete<_Hp, _Hp> | |
: private __check_complete<_Hp> | |
{ | |
}; | |
template <class _Tp> | |
struct __check_complete<_Tp> | |
{ | |
static_assert(sizeof(_Tp) > 0, "Type must be complete."); | |
}; | |
template <class _Tp> | |
struct __check_complete<_Tp&> | |
: private __check_complete<_Tp> | |
{ | |
}; | |
template <class _Tp> | |
struct __check_complete<_Tp&&> | |
: private __check_complete<_Tp> | |
{ | |
}; | |
template <class _Rp, class ..._Param> | |
struct __check_complete<_Rp (*)(_Param...)> | |
: private __check_complete<_Rp> | |
{ | |
}; | |
template <class ..._Param> | |
struct __check_complete<void (*)(_Param...)> | |
{ | |
}; | |
template <class _Rp, class ..._Param> | |
struct __check_complete<_Rp (_Param...)> | |
: private __check_complete<_Rp> | |
{ | |
}; | |
template <class ..._Param> | |
struct __check_complete<void (_Param...)> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...)> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) const> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) volatile> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) const volatile> | |
: private __check_complete<_Class> | |
{ | |
}; | |
#if __has_feature(cxx_reference_qualified_functions) | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) &> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) const&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) volatile&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) &&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) const&&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) volatile&&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
template <class _Rp, class _Class, class ..._Param> | |
struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&> | |
: private __check_complete<_Class> | |
{ | |
}; | |
#endif | |
template <class _Rp, class _Class> | |
struct __check_complete<_Rp _Class::*> | |
: private __check_complete<_Class> | |
{ | |
}; | |
// __invoke forward declarations | |
// fall back - none of the bullets | |
template <class ..._Args> | |
auto | |
__invoke(__any, _Args&& ...__args) | |
-> __nat; | |
// bullets 1 and 2 | |
template <class _Fp, class _A0, class ..._Args, | |
class = typename enable_if | |
< | |
is_member_function_pointer<typename remove_reference<_Fp>::type>::value && | |
is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type, | |
typename remove_reference<_A0>::type>::value | |
>::type | |
> | |
_LIBCPP_INLINE_VISIBILITY | |
auto | |
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) | |
-> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)); | |
template <class _Fp, class _A0, class ..._Args, | |
class = typename enable_if | |
< | |
is_member_function_pointer<typename remove_reference<_Fp>::type>::value && | |
!is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type, | |
typename remove_reference<_A0>::type>::value | |
>::type | |
> | |
_LIBCPP_INLINE_VISIBILITY | |
auto | |
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) | |
-> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)); | |
// bullets 3 and 4 | |
template <class _Fp, class _A0, | |
class = typename enable_if | |
< | |
is_member_object_pointer<typename remove_reference<_Fp>::type>::value && | |
is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType, | |
typename remove_reference<_A0>::type>::value | |
>::type | |
> | |
_LIBCPP_INLINE_VISIBILITY | |
auto | |
__invoke(_Fp&& __f, _A0&& __a0) | |
-> decltype(_VSTD::forward<_A0>(__a0).*__f); | |
template <class _Fp, class _A0, | |
class = typename enable_if | |
< | |
is_member_object_pointer<typename remove_reference<_Fp>::type>::value && | |
!is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType, | |
typename remove_reference<_A0>::type>::value | |
>::type | |
> | |
_LIBCPP_INLINE_VISIBILITY | |
auto | |
__invoke(_Fp&& __f, _A0&& __a0) | |
-> decltype((*_VSTD::forward<_A0>(__a0)).*__f); | |
// bullet 5 | |
template <class _Fp, class ..._Args> | |
_LIBCPP_INLINE_VISIBILITY | |
auto | |
__invoke(_Fp&& __f, _Args&& ...__args) | |
-> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)); | |
// __invokable | |
template <class _Fp, class ..._Args> | |
struct __invokable_imp | |
: private __check_complete<_Fp> | |
{ | |
typedef decltype( | |
__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...) | |
) type; | |
static const bool value = !is_same<type, __nat>::value; | |
}; | |
template <class _Fp, class ..._Args> | |
struct __invokable | |
: public integral_constant<bool, | |
__invokable_imp<_Fp, _Args...>::value> | |
{ | |
}; | |
// __invoke_of | |
template <bool _Invokable, class _Fp, class ..._Args> | |
struct __invoke_of_imp // false | |
{ | |
}; | |
template <class _Fp, class ..._Args> | |
struct __invoke_of_imp<true, _Fp, _Args...> | |
{ | |
typedef typename __invokable_imp<_Fp, _Args...>::type type; | |
}; | |
template <class _Fp, class ..._Args> | |
struct __invoke_of | |
: public __invoke_of_imp<__invokable<_Fp, _Args...>::value, _Fp, _Args...> | |
{ | |
}; | |
template <class _Fp, class ..._Args> | |
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)> | |
: public __invoke_of<_Fp, _Args...> | |
{ | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using result_of_t = typename result_of<_Tp>::type; | |
#endif | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY | |
#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
typename enable_if | |
< | |
is_move_constructible<_Tp>::value && | |
is_move_assignable<_Tp>::value | |
>::type | |
#else | |
void | |
#endif | |
swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && | |
is_nothrow_move_assignable<_Tp>::value) | |
{ | |
_Tp __t(_VSTD::move(__x)); | |
__x = _VSTD::move(__y); | |
__y = _VSTD::move(__t); | |
} | |
template <class _ForwardIterator1, class _ForwardIterator2> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) | |
// _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) | |
_NOEXCEPT_(_NOEXCEPT_(swap(*_VSTD::declval<_ForwardIterator1>(), | |
*_VSTD::declval<_ForwardIterator2>()))) | |
{ | |
swap(*__a, *__b); | |
} | |
// __swappable | |
namespace __detail | |
{ | |
using _VSTD::swap; | |
__nat swap(__any, __any); | |
template <class _Tp> | |
struct __swappable | |
{ | |
typedef decltype(swap(_VSTD::declval<_Tp&>(), _VSTD::declval<_Tp&>())) type; | |
static const bool value = !is_same<type, __nat>::value; | |
}; | |
} // __detail | |
template <class _Tp> | |
struct __is_swappable | |
: public integral_constant<bool, __detail::__swappable<_Tp>::value> | |
{ | |
}; | |
#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) | |
template <bool, class _Tp> | |
struct __is_nothrow_swappable_imp | |
: public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(), | |
_VSTD::declval<_Tp&>()))> | |
{ | |
}; | |
template <class _Tp> | |
struct __is_nothrow_swappable_imp<false, _Tp> | |
: public false_type | |
{ | |
}; | |
template <class _Tp> | |
struct __is_nothrow_swappable | |
: public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp> | |
{ | |
}; | |
#else // __has_feature(cxx_noexcept) | |
template <class _Tp> | |
struct __is_nothrow_swappable | |
: public false_type | |
{ | |
}; | |
#endif // __has_feature(cxx_noexcept) | |
#ifdef _LIBCPP_UNDERLYING_TYPE | |
template <class _Tp> | |
struct underlying_type | |
{ | |
typedef _LIBCPP_UNDERLYING_TYPE(_Tp) type; | |
}; | |
#if _LIBCPP_STD_VER > 11 | |
template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type; | |
#endif | |
#else // _LIBCPP_UNDERLYING_TYPE | |
template <class _Tp, bool _Support = false> | |
struct underlying_type | |
{ | |
static_assert(_Support, "The underyling_type trait requires compiler " | |
"support. Either no such support exists or " | |
"libc++ does not know how to use it."); | |
}; | |
#endif // _LIBCPP_UNDERLYING_TYPE | |
template <class _Tp, bool = std::is_enum<_Tp>::value> | |
struct __sfinae_underlying_type | |
{ | |
typedef typename underlying_type<_Tp>::type type; | |
typedef decltype(((type)1) + 0) __promoted_type; | |
}; | |
template <class _Tp> | |
struct __sfinae_underlying_type<_Tp, false> {}; | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
int __convert_to_integral(int __val) { return __val; } | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
unsigned __convert_to_integral(unsigned __val) { return __val; } | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
long __convert_to_integral(long __val) { return __val; } | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
unsigned long __convert_to_integral(unsigned long __val) { return __val; } | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
long long __convert_to_integral(long long __val) { return __val; } | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
unsigned long long __convert_to_integral(unsigned long long __val) {return __val; } | |
#ifndef _LIBCPP_HAS_NO_INT128 | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
__int128_t __convert_to_integral(__int128_t __val) { return __val; } | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
__uint128_t __convert_to_integral(__uint128_t __val) { return __val; } | |
#endif | |
template <class _Tp> | |
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE | |
typename __sfinae_underlying_type<_Tp>::__promoted_type | |
__convert_to_integral(_Tp __val) { return __val; } | |
#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
template <class _Tp> | |
struct __has_operator_addressof_member_imp | |
{ | |
template <class _Up> | |
static auto __test(int) | |
-> typename __select_2nd<decltype(_VSTD::declval<_Up>().operator&()), true_type>::type; | |
template <class> | |
static auto __test(long) -> false_type; | |
static const bool value = decltype(__test<_Tp>(0))::value; | |
}; | |
template <class _Tp> | |
struct __has_operator_addressof_free_imp | |
{ | |
template <class _Up> | |
static auto __test(int) | |
-> typename __select_2nd<decltype(operator&(_VSTD::declval<_Up>())), true_type>::type; | |
template <class> | |
static auto __test(long) -> false_type; | |
static const bool value = decltype(__test<_Tp>(0))::value; | |
}; | |
template <class _Tp> | |
struct __has_operator_addressof | |
: public integral_constant<bool, __has_operator_addressof_member_imp<_Tp>::value | |
|| __has_operator_addressof_free_imp<_Tp>::value> | |
{}; | |
#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE | |
#if _LIBCPP_STD_VER > 14 | |
template <class...> using void_t = void; | |
#endif | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // _LIBCPP_TYPE_TRAITS | |
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt | |
index 26dee67..38009a9 100644 | |
--- a/lib/CMakeLists.txt | |
+++ b/lib/CMakeLists.txt | |
@@ -1,139 +1,155 @@ | |
set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" PARENT_SCOPE) | |
# Get sources | |
file(GLOB LIBCXX_SOURCES ../src/*.cpp) | |
if(WIN32) | |
file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp) | |
list(APPEND LIBCXX_SOURCES ${LIBCXX_WIN32_SOURCES}) | |
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS") | |
file(GLOB LIBCXX_SOLARIS_SOURCES ../src/support/solaris/*.c) | |
list(APPEND LIBCXX_SOURCES ${LIBCXX_SOLARIS_SOURCES}) | |
+elseif(UNIX) | |
+ file(GLOB LIBCXX_PTHREAD_SOURCES ../src/support/pthread/*.cpp) | |
+ list(APPEND LIBCXX_SOURCES ${LIBCXX_PTHREAD_SOURCES}) | |
endif() | |
# Add all the headers to the project for IDEs. | |
if (MSVC_IDE OR XCODE) | |
file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/*) | |
if(WIN32) | |
file( GLOB LIBCXX_WIN32_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/support/win32/*.h) | |
list(APPEND LIBCXX_HEADERS ${LIBCXX_WIN32_HEADERS}) | |
endif() | |
+if(XCODE) | |
+ file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/support/pthread/*) | |
+ endif() | |
# Force them all into the headers dir on MSVC, otherwise they end up at | |
# project scope because they don't have extensions. | |
if (MSVC_IDE) | |
source_group("Header Files" FILES ${LIBCXX_HEADERS}) | |
endif() | |
endif() | |
if (LIBCXX_ENABLE_SHARED) | |
add_library(cxx SHARED ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) | |
else() | |
add_library(cxx STATIC ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) | |
endif() | |
if (DEFINED LIBCXX_CXX_ABI_DEPS) | |
add_dependencies(cxx LIBCXX_CXX_ABI_DEPS) | |
endif() | |
#if LIBCXX_CXX_ABI_LIBRARY_PATH is defined we want to add it to the search path. | |
add_link_flags_if(LIBCXX_CXX_ABI_LIBRARY_PATH "-L${LIBCXX_CXX_ABI_LIBRARY_PATH}") | |
add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}") | |
add_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "-Wl,--whole-archive" "-Wl,-Bstatic") | |
add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}") | |
add_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "-Wl,-Bdynamic" "-Wl,--no-whole-archive") | |
if (APPLE AND LLVM_USE_SANITIZER) | |
if ("${LLVM_USE_SANITIZER}" STREQUAL "Address") | |
set(LIBFILE "libclang_rt.asan_osx_dynamic.dylib") | |
elseif("${LLVM_USE_SANITIZER}" STREQUAL "Undefined") | |
set(LIBFILE "libclang_rt.ubsan_osx_dynamic.dylib") | |
else() | |
message(WARNING "LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X") | |
endif() | |
if (LIBFILE) | |
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=lib OUTPUT_VARIABLE LIBDIR RESULT_VARIABLE Result) | |
if (NOT ${Result} EQUAL "0") | |
message(FATAL "Failed to find library resource directory") | |
endif() | |
string(STRIP "${LIBDIR}" LIBDIR) | |
set(LIBDIR "${LIBDIR}/darwin/") | |
if (NOT IS_DIRECTORY "${LIBDIR}") | |
message(FATAL_ERROR "Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER") | |
endif() | |
set(LIBCXX_SANITIZER_LIBRARY "${LIBDIR}/${LIBFILE}") | |
set(LIBCXX_SANITIZER_LIBRARY "${LIBCXX_SANITIZER_LIBRARY}" PARENT_SCOPE) | |
message(STATUS "Manually linking compiler-rt library: ${LIBCXX_SANITIZER_LIBRARY}") | |
add_library_flags("${LIBCXX_SANITIZER_LIBRARY}") | |
add_link_flags("-Wl,-rpath,${LIBDIR}") | |
endif() | |
endif() | |
+# Thread API ================================================================== | |
+if(UNIX) | |
+ if(LIBCXX_HAS_PTHREAD_LIB) | |
+ add_definitions(-D_LIBCPP_THREAD_API=_LIBCPP_PTHREAD) | |
+ endif() | |
+elseif(WIN32) | |
+ add_definitions(-D_LIBCPP_THREAD_API=_LIBCPP_WIN32THREAD) | |
+endif() | |
+ | |
+ | |
# Generate library list. | |
add_library_flags_if(LIBCXX_HAS_PTHREAD_LIB pthread) | |
add_library_flags_if(LIBCXX_HAS_C_LIB c) | |
add_library_flags_if(LIBCXX_HAS_M_LIB m) | |
add_library_flags_if(LIBCXX_HAS_RT_LIB rt) | |
add_library_flags_if(LIBCXX_HAS_GCC_S_LIB gcc_s) | |
# Setup flags. | |
add_flags_if_supported(-fPIC) | |
add_link_flags_if_supported(-nodefaultlibs) | |
if ( APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL "libcxxabi" OR | |
LIBCXX_CXX_ABI_LIBNAME STREQUAL "none")) | |
if (NOT DEFINED LIBCXX_LIBCPPABI_VERSION) | |
set(LIBCXX_LIBCPPABI_VERSION "2") | |
endif() | |
if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" ) | |
add_definitions(-D__STRICT_ANSI__) | |
add_link_flags( | |
"-compatibility_version 1" | |
"-current_version 1" | |
"-install_name /usr/lib/libc++.1.dylib" | |
"-Wl,-reexport_library,/usr/lib/libc++abi.dylib" | |
"-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp" | |
"/usr/lib/libSystem.B.dylib") | |
else() | |
if ( ${CMAKE_OSX_SYSROOT} ) | |
list(FIND ${CMAKE_OSX_ARCHITECTURES} "armv7" OSX_HAS_ARMV7) | |
if (OSX_HAS_ARMV7) | |
set(OSX_RE_EXPORT_LINE | |
"${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib" | |
"-Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++sjlj-abi.exp") | |
else() | |
set(OSX_RE_EXPORT_LINE | |
"-Wl,-reexport_library,${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib") | |
endif() | |
else() | |
set (OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp") | |
endif() | |
add_link_flags( | |
"-compatibility_version 1" | |
"-install_name /usr/lib/libc++.1.dylib" | |
"-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp" | |
"${OSX_RE_EXPORT_LINE}" | |
"-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/notweak.exp" | |
"-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/weak.exp") | |
endif() | |
endif() | |
target_link_libraries(cxx ${LIBCXX_LIBRARIES}) | |
split_list(LIBCXX_COMPILE_FLAGS) | |
split_list(LIBCXX_LINK_FLAGS) | |
set_target_properties(cxx | |
PROPERTIES | |
COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" | |
LINK_FLAGS "${LIBCXX_LINK_FLAGS}" | |
OUTPUT_NAME "c++" | |
VERSION "1.0" | |
SOVERSION "1" | |
) | |
install(TARGETS cxx | |
LIBRARY DESTINATION lib${LIBCXX_LIBDIR_SUFFIX} | |
ARCHIVE DESTINATION lib${LIBCXX_LIBDIR_SUFFIX} | |
) | |
diff --git a/src/algorithm.cpp b/src/algorithm.cpp | |
index e548856..d668d5f 100644 | |
--- a/src/algorithm.cpp | |
+++ b/src/algorithm.cpp | |
@@ -1,91 +1,91 @@ | |
//===----------------------- algorithm.cpp --------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#include "algorithm" | |
#include "random" | |
#include "mutex" | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
template void __sort<__less<char>&, char*>(char*, char*, __less<char>&); | |
template void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); | |
template void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); | |
template void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); | |
template void __sort<__less<short>&, short*>(short*, short*, __less<short>&); | |
template void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); | |
template void __sort<__less<int>&, int*>(int*, int*, __less<int>&); | |
template void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); | |
template void __sort<__less<long>&, long*>(long*, long*, __less<long>&); | |
template void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); | |
template void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); | |
template void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); | |
template void __sort<__less<float>&, float*>(float*, float*, __less<float>&); | |
template void __sort<__less<double>&, double*>(double*, double*, __less<double>&); | |
template void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); | |
template bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&); | |
template bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); | |
template bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); | |
template bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); | |
template bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&); | |
template bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); | |
template bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&); | |
template bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); | |
template bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&); | |
template bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); | |
template bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); | |
template bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); | |
template bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&); | |
template bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&); | |
template bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); | |
template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&); | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
-static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER; | |
+static mutex __rs_mut; | |
#endif | |
unsigned __rs_default::__c_ = 0; | |
__rs_default::__rs_default() | |
{ | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
- pthread_mutex_lock(&__rs_mut); | |
+ __rs_mut.lock(); | |
#endif | |
__c_ = 1; | |
} | |
__rs_default::__rs_default(const __rs_default&) | |
{ | |
++__c_; | |
} | |
__rs_default::~__rs_default() | |
{ | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
if (--__c_ == 0) | |
- pthread_mutex_unlock(&__rs_mut); | |
+ __rs_mut.unlock(); | |
#else | |
--__c_; | |
#endif | |
} | |
__rs_default::result_type | |
__rs_default::operator()() | |
{ | |
static mt19937 __rs_g; | |
return __rs_g(); | |
} | |
__rs_default | |
__rs_get() | |
{ | |
return __rs_default(); | |
} | |
_LIBCPP_END_NAMESPACE_STD | |
diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp | |
index 5fd5fc8..4a465fd 100644 | |
--- a/src/condition_variable.cpp | |
+++ b/src/condition_variable.cpp | |
@@ -1,87 +1,69 @@ | |
//===-------------------- condition_variable.cpp --------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#include "__config" | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
#include "condition_variable" | |
#include "thread" | |
#include "system_error" | |
#include "cassert" | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
+using namespace __libcpp_support; | |
+ | |
condition_variable::~condition_variable() | |
{ | |
- pthread_cond_destroy(&__cv_); | |
+ __os_cond_var_destroy(&__cv_); | |
} | |
void | |
condition_variable::notify_one() _NOEXCEPT | |
{ | |
- pthread_cond_signal(&__cv_); | |
+ __os_cond_var_notify_one(&__cv_); | |
} | |
void | |
condition_variable::notify_all() _NOEXCEPT | |
{ | |
- pthread_cond_broadcast(&__cv_); | |
+ __os_cond_var_notify_all(&__cv_); | |
} | |
void | |
condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT | |
{ | |
if (!lk.owns_lock()) | |
__throw_system_error(EPERM, | |
"condition_variable::wait: mutex not locked"); | |
- int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); | |
+ int ec = __os_cond_var_wait(&__cv_, lk.mutex()->native_handle()); | |
if (ec) | |
__throw_system_error(ec, "condition_variable wait failed"); | |
} | |
void | |
condition_variable::__do_timed_wait(unique_lock<mutex>& lk, | |
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT | |
{ | |
- using namespace chrono; | |
if (!lk.owns_lock()) | |
__throw_system_error(EPERM, | |
"condition_variable::timed wait: mutex not locked"); | |
- nanoseconds d = tp.time_since_epoch(); | |
- if (d > nanoseconds(0x59682F000000E941)) | |
- d = nanoseconds(0x59682F000000E941); | |
- timespec ts; | |
- seconds s = duration_cast<seconds>(d); | |
- typedef decltype(ts.tv_sec) ts_sec; | |
- _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); | |
- if (s.count() < ts_sec_max) | |
- { | |
- ts.tv_sec = static_cast<ts_sec>(s.count()); | |
- ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); | |
- } | |
- else | |
- { | |
- ts.tv_sec = ts_sec_max; | |
- ts.tv_nsec = giga::num - 1; | |
- } | |
- int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); | |
- if (ec != 0 && ec != ETIMEDOUT) | |
- __throw_system_error(ec, "condition_variable timed_wait failed"); | |
+ __os_cond_var_timed_wait(&__cv_, lk.mutex()->native_handle(), tp); | |
} | |
void | |
notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) | |
{ | |
__thread_local_data()->notify_all_at_thread_exit(&cond, lk.release()); | |
} | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
diff --git a/src/memory.cpp b/src/memory.cpp | |
index 66fb143..3cc2e27 100644 | |
--- a/src/memory.cpp | |
+++ b/src/memory.cpp | |
@@ -1,228 +1,222 @@ | |
//===------------------------ memory.cpp ----------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#define _LIBCPP_BUILDING_MEMORY | |
#include "memory" | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
#include "mutex" | |
#include "thread" | |
#endif | |
#include "support/atomic_support.h" | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
namespace | |
{ | |
// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) | |
// should be sufficient for thread safety. | |
// See https://llvm.org/bugs/show_bug.cgi?id=22803 | |
template <class T> | |
inline T | |
increment(T& t) _NOEXCEPT | |
{ | |
return __libcpp_atomic_add(&t, 1, _AO_Relaxed); | |
} | |
template <class T> | |
inline T | |
decrement(T& t) _NOEXCEPT | |
{ | |
return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel); | |
} | |
} // namespace | |
const allocator_arg_t allocator_arg = allocator_arg_t(); | |
bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} | |
const char* | |
bad_weak_ptr::what() const _NOEXCEPT | |
{ | |
return "bad_weak_ptr"; | |
} | |
__shared_count::~__shared_count() | |
{ | |
} | |
void | |
__shared_count::__add_shared() _NOEXCEPT | |
{ | |
increment(__shared_owners_); | |
} | |
bool | |
__shared_count::__release_shared() _NOEXCEPT | |
{ | |
if (decrement(__shared_owners_) == -1) | |
{ | |
__on_zero_shared(); | |
return true; | |
} | |
return false; | |
} | |
__shared_weak_count::~__shared_weak_count() | |
{ | |
} | |
void | |
__shared_weak_count::__add_shared() _NOEXCEPT | |
{ | |
__shared_count::__add_shared(); | |
} | |
void | |
__shared_weak_count::__add_weak() _NOEXCEPT | |
{ | |
increment(__shared_weak_owners_); | |
} | |
void | |
__shared_weak_count::__release_shared() _NOEXCEPT | |
{ | |
if (__shared_count::__release_shared()) | |
__release_weak(); | |
} | |
void | |
__shared_weak_count::__release_weak() _NOEXCEPT | |
{ | |
if (decrement(__shared_weak_owners_) == -1) | |
__on_zero_shared_weak(); | |
} | |
__shared_weak_count* | |
__shared_weak_count::lock() _NOEXCEPT | |
{ | |
long object_owners = __libcpp_atomic_load(&__shared_owners_); | |
while (object_owners != -1) | |
{ | |
if (__libcpp_atomic_compare_exchange(&__shared_owners_, | |
&object_owners, | |
object_owners+1)) | |
return this; | |
} | |
return 0; | |
} | |
#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC) | |
const void* | |
__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT | |
{ | |
return 0; | |
} | |
#endif // _LIBCPP_NO_RTTI | |
#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) | |
static const std::size_t __sp_mut_count = 16; | |
-static pthread_mutex_t mut_back_imp[__sp_mut_count] = | |
-{ | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER | |
-}; | |
+static mutex mut_back_imp[__sp_mut_count]; | |
-static mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp); | |
+static mutex* mut_back = mut_back_imp; | |
_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT | |
: __lx(p) | |
{ | |
} | |
void | |
__sp_mut::lock() _NOEXCEPT | |
{ | |
mutex& m = *static_cast<mutex*>(__lx); | |
unsigned count = 0; | |
while (!m.try_lock()) | |
{ | |
if (++count > 16) | |
{ | |
m.lock(); | |
break; | |
} | |
this_thread::yield(); | |
} | |
} | |
void | |
__sp_mut::unlock() _NOEXCEPT | |
{ | |
static_cast<mutex*>(__lx)->unlock(); | |
} | |
__sp_mut& | |
__get_sp_mut(const void* p) | |
{ | |
static __sp_mut muts[__sp_mut_count] | |
{ | |
&mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3], | |
&mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7], | |
&mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11], | |
&mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15] | |
}; | |
return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; | |
} | |
#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS | |
void | |
declare_reachable(void*) | |
{ | |
} | |
void | |
declare_no_pointers(char*, size_t) | |
{ | |
} | |
void | |
undeclare_no_pointers(char*, size_t) | |
{ | |
} | |
pointer_safety | |
get_pointer_safety() _NOEXCEPT | |
{ | |
return pointer_safety::relaxed; | |
} | |
void* | |
__undeclare_reachable(void* p) | |
{ | |
return p; | |
} | |
void* | |
align(size_t alignment, size_t size, void*& ptr, size_t& space) | |
{ | |
void* r = nullptr; | |
if (size <= space) | |
{ | |
char* p1 = static_cast<char*>(ptr); | |
char* p2 = reinterpret_cast<char*>(reinterpret_cast<size_t>(p1 + (alignment - 1)) & -alignment); | |
size_t d = static_cast<size_t>(p2 - p1); | |
if (d <= space - size) | |
{ | |
r = p2; | |
ptr = r; | |
space -= d; | |
} | |
} | |
return r; | |
} | |
_LIBCPP_END_NAMESPACE_STD | |
diff --git a/src/mutex.cpp b/src/mutex.cpp | |
index 5f8ba0a..27c16f5 100644 | |
--- a/src/mutex.cpp | |
+++ b/src/mutex.cpp | |
@@ -1,284 +1,191 @@ | |
//===------------------------- mutex.cpp ----------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#define _LIBCPP_BUILDING_MUTEX | |
#include "mutex" | |
#include "limits" | |
#include "system_error" | |
#include "cassert" | |
-#include "support/atomic_support.h" | |
+#include "support/thread.h" | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
const defer_lock_t defer_lock = {}; | |
const try_to_lock_t try_to_lock = {}; | |
const adopt_lock_t adopt_lock = {}; | |
+using namespace __libcpp_support; | |
+ | |
mutex::~mutex() | |
{ | |
- pthread_mutex_destroy(&__m_); | |
+ __os_mutex_destroy(&__m_); | |
} | |
void | |
mutex::lock() | |
{ | |
- int ec = pthread_mutex_lock(&__m_); | |
+ int ec = __os_mutex_lock(&__m_); | |
if (ec) | |
__throw_system_error(ec, "mutex lock failed"); | |
} | |
bool | |
mutex::try_lock() _NOEXCEPT | |
{ | |
- return pthread_mutex_trylock(&__m_) == 0; | |
+ return __os_mutex_trylock(&__m_) == 0; | |
} | |
void | |
mutex::unlock() _NOEXCEPT | |
{ | |
- int ec = pthread_mutex_unlock(&__m_); | |
+ int ec = __os_mutex_unlock(&__m_); | |
(void)ec; | |
assert(ec == 0); | |
} | |
// recursive_mutex | |
recursive_mutex::recursive_mutex() | |
{ | |
- pthread_mutexattr_t attr; | |
- int ec = pthread_mutexattr_init(&attr); | |
- if (ec) | |
- goto fail; | |
- ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |
- if (ec) | |
- { | |
- pthread_mutexattr_destroy(&attr); | |
- goto fail; | |
- } | |
- ec = pthread_mutex_init(&__m_, &attr); | |
- if (ec) | |
- { | |
- pthread_mutexattr_destroy(&attr); | |
- goto fail; | |
- } | |
- ec = pthread_mutexattr_destroy(&attr); | |
- if (ec) | |
- { | |
- pthread_mutex_destroy(&__m_); | |
- goto fail; | |
- } | |
- return; | |
-fail: | |
- __throw_system_error(ec, "recursive_mutex constructor failed"); | |
+ __os_recursive_mutex_init(&__m_); | |
} | |
recursive_mutex::~recursive_mutex() | |
{ | |
- int e = pthread_mutex_destroy(&__m_); | |
+ int e = __os_recursive_mutex_destroy(&__m_); | |
(void)e; | |
assert(e == 0); | |
} | |
void | |
recursive_mutex::lock() | |
{ | |
- int ec = pthread_mutex_lock(&__m_); | |
+ int ec = __os_recursive_mutex_lock(&__m_); | |
if (ec) | |
__throw_system_error(ec, "recursive_mutex lock failed"); | |
} | |
void | |
recursive_mutex::unlock() _NOEXCEPT | |
{ | |
- int e = pthread_mutex_unlock(&__m_); | |
+ int e = __os_recursive_mutex_unlock(&__m_); | |
(void)e; | |
assert(e == 0); | |
} | |
bool | |
recursive_mutex::try_lock() _NOEXCEPT | |
{ | |
- return pthread_mutex_trylock(&__m_) == 0; | |
+ return __os_recursive_mutex_trylock(&__m_) == 0; | |
} | |
// timed_mutex | |
timed_mutex::timed_mutex() | |
: __locked_(false) | |
{ | |
} | |
timed_mutex::~timed_mutex() | |
{ | |
lock_guard<mutex> _(__m_); | |
} | |
void | |
timed_mutex::lock() | |
{ | |
unique_lock<mutex> lk(__m_); | |
while (__locked_) | |
__cv_.wait(lk); | |
__locked_ = true; | |
} | |
bool | |
timed_mutex::try_lock() _NOEXCEPT | |
{ | |
unique_lock<mutex> lk(__m_, try_to_lock); | |
if (lk.owns_lock() && !__locked_) | |
{ | |
__locked_ = true; | |
return true; | |
} | |
return false; | |
} | |
void | |
timed_mutex::unlock() _NOEXCEPT | |
{ | |
lock_guard<mutex> _(__m_); | |
__locked_ = false; | |
__cv_.notify_one(); | |
} | |
// recursive_timed_mutex | |
recursive_timed_mutex::recursive_timed_mutex() | |
: __count_(0), | |
__id_(0) | |
{ | |
} | |
recursive_timed_mutex::~recursive_timed_mutex() | |
{ | |
lock_guard<mutex> _(__m_); | |
} | |
void | |
recursive_timed_mutex::lock() | |
{ | |
- pthread_t id = pthread_self(); | |
+ __os_thread_id id = __os_get_current_thread_id(); | |
unique_lock<mutex> lk(__m_); | |
- if (pthread_equal(id, __id_)) | |
+ if (__os_thread_id_compare(id, __id_) == 0) | |
{ | |
if (__count_ == numeric_limits<size_t>::max()) | |
__throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); | |
++__count_; | |
return; | |
} | |
while (__count_ != 0) | |
__cv_.wait(lk); | |
__count_ = 1; | |
__id_ = id; | |
} | |
bool | |
recursive_timed_mutex::try_lock() _NOEXCEPT | |
{ | |
- pthread_t id = pthread_self(); | |
+ __os_thread_id id = __os_get_current_thread_id(); | |
unique_lock<mutex> lk(__m_, try_to_lock); | |
- if (lk.owns_lock() && (__count_ == 0 || pthread_equal(id, __id_))) | |
+ if (lk.owns_lock() && (__count_ == 0 || __os_thread_id_compare(id, __id_) == 0)) | |
{ | |
if (__count_ == numeric_limits<size_t>::max()) | |
return false; | |
++__count_; | |
__id_ = id; | |
return true; | |
} | |
return false; | |
} | |
void | |
recursive_timed_mutex::unlock() _NOEXCEPT | |
{ | |
unique_lock<mutex> lk(__m_); | |
if (--__count_ == 0) | |
{ | |
__id_ = 0; | |
lk.unlock(); | |
__cv_.notify_one(); | |
} | |
} | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
-// If dispatch_once_f ever handles C++ exceptions, and if one can get to it | |
-// without illegal macros (unexpected macros not beginning with _UpperCase or | |
-// __lowercase), and if it stops spinning waiting threads, then call_once should | |
-// call into dispatch_once_f instead of here. Relevant radar this code needs to | |
-// keep in sync with: 7741191. | |
- | |
-#ifndef _LIBCPP_HAS_NO_THREADS | |
-static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | |
-static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; | |
-#endif | |
- | |
-/// NOTE: Changes to flag are done via relaxed atomic stores | |
-/// even though the accesses are protected by a mutex because threads | |
-/// just entering 'call_once` concurrently read from flag. | |
-void | |
-__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) | |
-{ | |
-#if defined(_LIBCPP_HAS_NO_THREADS) | |
- if (flag == 0) | |
- { | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- try | |
- { | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- flag = 1; | |
- func(arg); | |
- flag = ~0ul; | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- } | |
- catch (...) | |
- { | |
- flag = 0ul; | |
- throw; | |
- } | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- } | |
-#else // !_LIBCPP_HAS_NO_THREADS | |
- pthread_mutex_lock(&mut); | |
- while (flag == 1) | |
- pthread_cond_wait(&cv, &mut); | |
- if (flag == 0) | |
- { | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- try | |
- { | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- __libcpp_relaxed_store(&flag, 1ul); | |
- pthread_mutex_unlock(&mut); | |
- func(arg); | |
- pthread_mutex_lock(&mut); | |
- __libcpp_relaxed_store(&flag, ~0ul); | |
- pthread_mutex_unlock(&mut); | |
- pthread_cond_broadcast(&cv); | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- } | |
- catch (...) | |
- { | |
- pthread_mutex_lock(&mut); | |
- __libcpp_relaxed_store(&flag, 0ul); | |
- pthread_mutex_unlock(&mut); | |
- pthread_cond_broadcast(&cv); | |
- throw; | |
- } | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- } | |
- else | |
- pthread_mutex_unlock(&mut); | |
-#endif // !_LIBCPP_HAS_NO_THREADS | |
- | |
-} | |
- | |
_LIBCPP_END_NAMESPACE_STD | |
diff --git a/src/support/pthread/condition_variable.cpp b/src/support/pthread/condition_variable.cpp | |
new file mode 100644 | |
index 0000000..8b44740 | |
--- /dev/null | |
+++ b/src/support/pthread/condition_variable.cpp | |
@@ -0,0 +1,55 @@ | |
+// -*- C++ -*- | |
+//===---------------------- support/pthread/thread.cpp --------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "__config" | |
+ | |
+#include <chrono> | |
+#include "system_error" | |
+#define _LIBCPP_INCLUDE_THREAD_API | |
+#include <support/pthread/condition_variable.h> | |
+#undef _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+_LIBCPP_BEGIN_NAMESPACE_STD | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+ | |
+namespace __libcpp_support | |
+{ | |
+ | |
+void __os_cond_var_timed_wait(__os_cond_var* cv, | |
+ __os_mutex* m, | |
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) | |
+{ | |
+ using namespace chrono; | |
+ nanoseconds d = tp.time_since_epoch(); | |
+ if (d > nanoseconds(0x59682F000000E941)) | |
+ d = nanoseconds(0x59682F000000E941); | |
+ timespec ts; | |
+ seconds s = duration_cast<seconds>(d); | |
+ typedef decltype(ts.tv_sec) ts_sec; | |
+ _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); | |
+ if (s.count() < ts_sec_max) | |
+ { | |
+ ts.tv_sec = static_cast<ts_sec>(s.count()); | |
+ ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); | |
+ } | |
+ else | |
+ { | |
+ ts.tv_sec = ts_sec_max; | |
+ ts.tv_nsec = giga::num - 1; | |
+ } | |
+ int ec = pthread_cond_timedwait(cv, m, &ts); | |
+ if (ec != 0 && ec != ETIMEDOUT) | |
+ __throw_system_error(ec, "condition_variable timed_wait failed"); | |
+} | |
+ | |
+} //namespace __libcpp_support | |
+ | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+_LIBCPP_END_NAMESPACE_STD | |
diff --git a/src/support/pthread/mutex.cpp b/src/support/pthread/mutex.cpp | |
new file mode 100644 | |
index 0000000..7e01ac8 | |
--- /dev/null | |
+++ b/src/support/pthread/mutex.cpp | |
@@ -0,0 +1,131 @@ | |
+// -*- C++ -*- | |
+//===---------------------- support/pthread/thread.cpp --------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "__config" | |
+ | |
+#include <chrono> | |
+#include <system_error> | |
+#include "../atomic_support.h" | |
+ | |
+#define _LIBCPP_INCLUDE_THREAD_API | |
+#include <support/pthread/mutex.h> | |
+#undef _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+_LIBCPP_BEGIN_NAMESPACE_STD | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+ | |
+namespace __libcpp_support | |
+{ | |
+ | |
+void __os_recursive_mutex_init(__os_mutex* __m) | |
+{ | |
+ pthread_mutexattr_t attr; | |
+ int ec = pthread_mutexattr_init(&attr); | |
+ if (ec) | |
+ goto fail; | |
+ ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |
+ if (ec) | |
+ { | |
+ pthread_mutexattr_destroy(&attr); | |
+ goto fail; | |
+ } | |
+ ec = pthread_mutex_init(__m, &attr); | |
+ if (ec) | |
+ { | |
+ pthread_mutexattr_destroy(&attr); | |
+ goto fail; | |
+ } | |
+ ec = pthread_mutexattr_destroy(&attr); | |
+ if (ec) | |
+ { | |
+ pthread_mutex_destroy(__m); | |
+ goto fail; | |
+ } | |
+ return; | |
+fail: | |
+ __throw_system_error(ec, "recursive_mutex constructor failed"); | |
+} | |
+ | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+ | |
+// If dispatch_once_f ever handles C++ exceptions, and if one can get to it | |
+// without illegal macros (unexpected macros not beginning with _UpperCase or | |
+// __lowercase), and if it stops spinning waiting threads, then call_once should | |
+// call into dispatch_once_f instead of here. Relevant radar this code needs to | |
+// keep in sync with: 7741191. | |
+ | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | |
+static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; | |
+#endif | |
+ | |
+/// NOTE: Changes to flag are done via relaxed atomic stores | |
+/// even though the accesses are protected by a mutex because threads | |
+/// just entering 'call_once` concurrently read from flag. | |
+void | |
+__os_call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) | |
+{ | |
+#if defined(_LIBCPP_HAS_NO_THREADS) | |
+ if (flag == 0) | |
+ { | |
+#ifndef _LIBCPP_NO_EXCEPTIONS | |
+ try | |
+ { | |
+#endif // _LIBCPP_NO_EXCEPTIONS | |
+ flag = 1; | |
+ func(arg); | |
+ flag = ~0ul; | |
+#ifndef _LIBCPP_NO_EXCEPTIONS | |
+ } | |
+ catch (...) | |
+ { | |
+ flag = 0ul; | |
+ throw; | |
+ } | |
+#endif // _LIBCPP_NO_EXCEPTIONS | |
+ } | |
+#else // !_LIBCPP_HAS_NO_THREADS | |
+ pthread_mutex_lock(&mut); | |
+ while (flag == 1) | |
+ pthread_cond_wait(&cv, &mut); | |
+ if (flag == 0) | |
+ { | |
+#ifndef _LIBCPP_NO_EXCEPTIONS | |
+ try | |
+ { | |
+#endif // _LIBCPP_NO_EXCEPTIONS | |
+ __libcpp_relaxed_store(&flag, 1ul); | |
+ pthread_mutex_unlock(&mut); | |
+ func(arg); | |
+ pthread_mutex_lock(&mut); | |
+ __libcpp_relaxed_store(&flag, ~0ul); | |
+ pthread_mutex_unlock(&mut); | |
+ pthread_cond_broadcast(&cv); | |
+#ifndef _LIBCPP_NO_EXCEPTIONS | |
+ } | |
+ catch (...) | |
+ { | |
+ pthread_mutex_lock(&mut); | |
+ __libcpp_relaxed_store(&flag, 0ul); | |
+ pthread_mutex_unlock(&mut); | |
+ pthread_cond_broadcast(&cv); | |
+ throw; | |
+ } | |
+#endif // _LIBCPP_NO_EXCEPTIONS | |
+ } | |
+ else | |
+ pthread_mutex_unlock(&mut); | |
+#endif // !_LIBCPP_HAS_NO_THREADS | |
+ | |
+} | |
+ | |
+} //namespace __libcpp_support | |
+ | |
+_LIBCPP_END_NAMESPACE_STD | |
diff --git a/src/support/pthread/thread.cpp b/src/support/pthread/thread.cpp | |
new file mode 100644 | |
index 0000000..74ba0dd | |
--- /dev/null | |
+++ b/src/support/pthread/thread.cpp | |
@@ -0,0 +1,54 @@ | |
+// -*- C++ -*- | |
+//===---------------------- support/pthread/thread.cpp --------------------===// | |
+// | |
+// The LLVM Compiler Infrastructure | |
+// | |
+// This file is dual licensed under the MIT and the University of Illinois Open | |
+// Source Licenses. See LICENSE.TXT for details. | |
+// | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#include "__config" | |
+ | |
+#include <ostream> | |
+#include <chrono> | |
+#define _LIBCPP_INCLUDE_THREAD_API | |
+#include <support/pthread/thread.h> | |
+#undef _LIBCPP_INCLUDE_THREAD_API | |
+ | |
+_LIBCPP_BEGIN_NAMESPACE_STD | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+ | |
+namespace __libcpp_support | |
+{ | |
+ | |
+void | |
+__os_sleep_for(const chrono::nanoseconds& ns) | |
+{ | |
+ using namespace chrono; | |
+ if (ns > nanoseconds::zero()) | |
+ { | |
+ seconds s = duration_cast<seconds>(ns); | |
+ timespec ts; | |
+ typedef decltype(ts.tv_sec) ts_sec; | |
+ _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); | |
+ if (s.count() < ts_sec_max) | |
+ { | |
+ ts.tv_sec = static_cast<ts_sec>(s.count()); | |
+ ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count()); | |
+ } | |
+ else | |
+ { | |
+ ts.tv_sec = ts_sec_max; | |
+ ts.tv_nsec = giga::num - 1; | |
+ } | |
+ | |
+ while (nanosleep(&ts, &ts) == -1 && errno == EINTR) | |
+ ; | |
+ } | |
+} | |
+ | |
+} //namespace __libcpp_support | |
+ | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+_LIBCPP_END_NAMESPACE_STD | |
diff --git a/src/thread.cpp b/src/thread.cpp | |
index bd27f28..8248807 100644 | |
--- a/src/thread.cpp | |
+++ b/src/thread.cpp | |
@@ -1,232 +1,203 @@ | |
//===------------------------- thread.cpp----------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#include "__config" | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
#include "thread" | |
#include "exception" | |
#include "vector" | |
#include "future" | |
#include "limits" | |
#include <sys/types.h> | |
#if !defined(_WIN32) | |
# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__) | |
# include <sys/sysctl.h> | |
# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__) | |
# include <unistd.h> | |
#endif // !_WIN32 | |
#if defined(__NetBSD__) | |
#pragma weak pthread_create // Do not create libpthread dependency | |
#endif | |
#if defined(_WIN32) | |
#include <windows.h> | |
#endif | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
+using namespace __libcpp_support; | |
+ | |
thread::~thread() | |
{ | |
if (__t_ != 0) | |
terminate(); | |
} | |
void | |
thread::join() | |
{ | |
- int ec = pthread_join(__t_, 0); | |
+ int ec = __os_thread_join(__t_); | |
#ifndef _LIBCPP_NO_EXCEPTIONS | |
if (ec) | |
throw system_error(error_code(ec, system_category()), "thread::join failed"); | |
#else | |
(void)ec; | |
#endif // _LIBCPP_NO_EXCEPTIONS | |
__t_ = 0; | |
} | |
void | |
thread::detach() | |
{ | |
int ec = EINVAL; | |
if (__t_ != 0) | |
{ | |
- ec = pthread_detach(__t_); | |
+ ec = __os_thread_detach(__t_); | |
if (ec == 0) | |
__t_ = 0; | |
} | |
#ifndef _LIBCPP_NO_EXCEPTIONS | |
if (ec) | |
throw system_error(error_code(ec, system_category()), "thread::detach failed"); | |
#endif // _LIBCPP_NO_EXCEPTIONS | |
} | |
unsigned | |
thread::hardware_concurrency() _NOEXCEPT | |
{ | |
#if defined(CTL_HW) && defined(HW_NCPU) | |
unsigned n; | |
int mib[2] = {CTL_HW, HW_NCPU}; | |
std::size_t s = sizeof(n); | |
sysctl(mib, 2, &n, &s, 0, 0); | |
return n; | |
#elif defined(_SC_NPROCESSORS_ONLN) | |
long result = sysconf(_SC_NPROCESSORS_ONLN); | |
// sysconf returns -1 if the name is invalid, the option does not exist or | |
// does not have a definite limit. | |
// if sysconf returns some other negative number, we have no idea | |
// what is going on. Default to something safe. | |
if (result < 0) | |
return 0; | |
return static_cast<unsigned>(result); | |
#elif defined(_WIN32) | |
SYSTEM_INFO info; | |
GetSystemInfo(&info); | |
return info.dwNumberOfProcessors; | |
#else // defined(CTL_HW) && defined(HW_NCPU) | |
// TODO: grovel through /proc or check cpuid on x86 and similar | |
// instructions on other architectures. | |
# if defined(_MSC_VER) && ! defined(__clang__) | |
_LIBCPP_WARNING("hardware_concurrency not yet implemented") | |
# else | |
# warning hardware_concurrency not yet implemented | |
# endif | |
return 0; // Means not computable [thread.thread.static] | |
#endif // defined(CTL_HW) && defined(HW_NCPU) | |
} | |
-namespace this_thread | |
-{ | |
- | |
-void | |
-sleep_for(const chrono::nanoseconds& ns) | |
-{ | |
- using namespace chrono; | |
- if (ns > nanoseconds::zero()) | |
- { | |
- seconds s = duration_cast<seconds>(ns); | |
- timespec ts; | |
- typedef decltype(ts.tv_sec) ts_sec; | |
- _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); | |
- if (s.count() < ts_sec_max) | |
- { | |
- ts.tv_sec = static_cast<ts_sec>(s.count()); | |
- ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count()); | |
- } | |
- else | |
- { | |
- ts.tv_sec = ts_sec_max; | |
- ts.tv_nsec = giga::num - 1; | |
- } | |
- | |
- while (nanosleep(&ts, &ts) == -1 && errno == EINTR) | |
- ; | |
- } | |
-} | |
- | |
-} // this_thread | |
- | |
__thread_specific_ptr<__thread_struct>& | |
__thread_local_data() | |
{ | |
static __thread_specific_ptr<__thread_struct> __p; | |
return __p; | |
} | |
// __thread_struct_imp | |
template <class T> | |
class _LIBCPP_HIDDEN __hidden_allocator | |
{ | |
public: | |
typedef T value_type; | |
T* allocate(size_t __n) | |
{return static_cast<T*>(::operator new(__n * sizeof(T)));} | |
void deallocate(T* __p, size_t) {::operator delete(static_cast<void*>(__p));} | |
size_t max_size() const {return size_t(~0) / sizeof(T);} | |
}; | |
class _LIBCPP_HIDDEN __thread_struct_imp | |
{ | |
typedef vector<__assoc_sub_state*, | |
__hidden_allocator<__assoc_sub_state*> > _AsyncStates; | |
typedef vector<pair<condition_variable*, mutex*>, | |
__hidden_allocator<pair<condition_variable*, mutex*> > > _Notify; | |
_AsyncStates async_states_; | |
_Notify notify_; | |
__thread_struct_imp(const __thread_struct_imp&); | |
__thread_struct_imp& operator=(const __thread_struct_imp&); | |
public: | |
__thread_struct_imp() {} | |
~__thread_struct_imp(); | |
void notify_all_at_thread_exit(condition_variable* cv, mutex* m); | |
void __make_ready_at_thread_exit(__assoc_sub_state* __s); | |
}; | |
__thread_struct_imp::~__thread_struct_imp() | |
{ | |
for (_Notify::iterator i = notify_.begin(), e = notify_.end(); | |
i != e; ++i) | |
{ | |
i->second->unlock(); | |
i->first->notify_all(); | |
} | |
for (_AsyncStates::iterator i = async_states_.begin(), e = async_states_.end(); | |
i != e; ++i) | |
{ | |
(*i)->__make_ready(); | |
(*i)->__release_shared(); | |
} | |
} | |
void | |
__thread_struct_imp::notify_all_at_thread_exit(condition_variable* cv, mutex* m) | |
{ | |
notify_.push_back(pair<condition_variable*, mutex*>(cv, m)); | |
} | |
void | |
__thread_struct_imp::__make_ready_at_thread_exit(__assoc_sub_state* __s) | |
{ | |
async_states_.push_back(__s); | |
__s->__add_shared(); | |
} | |
// __thread_struct | |
__thread_struct::__thread_struct() | |
: __p_(new __thread_struct_imp) | |
{ | |
} | |
__thread_struct::~__thread_struct() | |
{ | |
delete __p_; | |
} | |
void | |
__thread_struct::notify_all_at_thread_exit(condition_variable* cv, mutex* m) | |
{ | |
__p_->notify_all_at_thread_exit(cv, m); | |
} | |
void | |
__thread_struct::__make_ready_at_thread_exit(__assoc_sub_state* __s) | |
{ | |
__p_->__make_ready_at_thread_exit(__s); | |
} | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // !_LIBCPP_HAS_NO_THREADS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment