Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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 "llvm-bugs@lists.llvm.org")
# 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 {};