Merge to upstream r244462.
Change-Id: I97e4a2e1d843ad20a9225a31bacc7b1a6e9d8f4f
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 230a3c6..be6fbbe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,18 +3,21 @@
#===============================================================================
# Setup Project
#===============================================================================
-
-project(libcxx CXX C)
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 "llvmbugs@cs.uiuc.edu")
+set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org")
# Add path for custom modules
set(CMAKE_MODULE_PATH
@@ -30,45 +33,95 @@
build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there."
)
-if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
- set(LIBCXX_LIBDIR_SUFFIX "" CACHE STRING
- "Define suffix of library directory name (32/64)")
-
- set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
-
- set(LIBCXX_BUILT_STANDALONE 1)
-else()
- set(LIBCXX_LIBDIR_SUFFIX ${LLVM_LIBDIR_SUFFIX})
+# 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
#===============================================================================
-# Define 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_ASSERTIONS "Enable assertions independent of build mode." ON)
-option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
-option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
-option(LIBCXX_ENABLE_CXX1Y "Enable -std=c++1y and use of c++1y language features if the compiler supports it." OFF)
-option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." 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_BUILD_32_BITS "Build 32 bit libc++" OFF)
+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)
-option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON)
-option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
-option(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "Statically link the ABI library" OFF)
-set(LIBCXX_SYSROOT "" CACHE STRING "Use alternate sysroot.")
-set(LIBCXX_GCC_TOOLCHAIN "" CACHE STRING "Use alternate GCC toolchain.")
-if (LIBCXX_BUILT_STANDALONE)
- set(LLVM_USE_SANITIZER "" CACHE STRING
- "Define the sanitizer used to build the library and tests")
+
+# 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")
@@ -77,23 +130,6 @@
endif()
endif()
-set(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++)
-if (NOT LIBCXX_CXX_ABI)
- if (NOT DEFINED LIBCXX_BUILT_STANDALONE AND
- IS_DIRECTORY "${CMAKE_SOURCE_DIR}/projects/libcxxabi")
- set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
- set(LIBCXX_LIBCXXABI_INCLUDE_PATHS "${CMAKE_SOURCE_DIR}/projects/libcxxabi/include")
- set(LIBCXX_CXX_ABI_INTREE 1)
- else ()
- set(LIBCXX_CXX_ABI_LIBNAME "none")
- endif ()
-else ()
- set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}")
-endif ()
-set(LIBCXX_CXX_ABI "${LIBCXX_CXX_ABI}" CACHE STRING
- "Specify C++ ABI library to use." FORCE)
-set_property(CACHE LIBCXX_CXX_ABI PROPERTY STRINGS ;${CXXABIS})
-
#===============================================================================
# Configure System
#===============================================================================
@@ -103,202 +139,155 @@
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_CXX_FLAGS "")
set(LIBCXX_COMPILE_FLAGS "")
set(LIBCXX_LINK_FLAGS "")
+set(LIBCXX_LIBRARIES "")
# Configure compiler.
include(config-ix)
-# Configure ABI library
-include(HandleLibCXXABI)
+
+# 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
#===============================================================================
-# Get required flags.
+include(HandleLibCXXABI) # Steup 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.
-if (MSVC)
- # 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.
-else()
- if (LIBCXX_HAS_NOSTDINCXX_FLAG)
- list(APPEND LIBCXX_COMPILE_FLAGS -nostdinc++)
- string(REPLACE "-stdlib=libc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- string(REPLACE "-stdlib=libstdc++" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- endif()
- # If c++1y has been enabled then attempt to use it. Fail if it is no supported
- # by the compiler. Otherwise choose c++11 and ensure the compiler supports it.
- if (LIBCXX_ENABLE_CXX1Y)
- if (LIBCXX_HAS_STDCXX1Y_FLAG)
- set(LIBCXX_STD_VERSION c++1y)
- else()
- message(FATAL_ERROR "c++1y was enabled but the compiler does not support it.")
- endif()
- else()
- if (LIBCXX_HAS_STDCXX11_FLAG)
- set(LIBCXX_STD_VERSION c++11)
- else()
- message(FATAL_ERROR "c++11 is required by libc++ but is not supported by the compiler")
- endif()
- endif()
- # LIBCXX_STD_VERSION should always be set at this point.
- list(APPEND LIBCXX_CXX_FLAGS "-std=${LIBCXX_STD_VERSION}")
-endif()
+# 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++)
-macro(append_if list condition var)
- if (${condition})
- list(APPEND ${list} ${var})
- endif()
-endmacro()
+# 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}")
-# Get warning flags
-if (NOT MSVC)
- append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WALL_FLAG -Wall)
- list(APPEND LIBCXX_COMPILE_FLAGS -Werror=return-type)
-endif()
-
-append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_W_FLAG -W)
-append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG -Wno-unused-parameter)
-append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings)
-append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WNO_LONG_LONG_FLAG -Wno-long-long)
+# 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)
- append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WERROR_FLAG -Werror)
- append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WX_FLAG -WX)
+ add_compile_flags_if_supported(-Werror)
+ add_compile_flags_if_supported(-WX)
else()
- append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_WNO_ERROR_FLAG -Wno-error)
- append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_NO_WX_FLAG -WX-)
+ # 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)
- append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_PEDANTIC_FLAG -pedantic)
+ add_compile_flags_if_supported(-pedantic)
endif()
-# Get feature flags.
-# Exceptions
+# 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.
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_EHSC_FLAG -EHsc)
+ add_compile_flags_if_supported(-EHsc)
else()
- list(APPEND LIBCXX_CXX_FLAGS -D_LIBCPP_NO_EXCEPTIONS)
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_NO_EHS_FLAG -EHs-)
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_NO_EHA_FLAG -EHa-)
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions)
+ add_definitions(-D_LIBCPP_NO_EXCEPTIONS)
+ add_compile_flags_if_supported(-EHs- -EHa-)
+ add_compile_flags_if_supported(-fno-exceptions)
endif()
-# RTTI
+
+# RTTI flags ==================================================================
if (NOT LIBCXX_ENABLE_RTTI)
- list(APPEND LIBCXX_CXX_FLAGS -D_LIBCPP_NO_RTTI)
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_NO_GR_FLAG -GR-)
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_FNO_RTTI_FLAG -fno-rtti)
+ add_definitions(-D_LIBCPP_NO_RTTI)
+ add_compile_flags_if_supported(-GR-)
+ add_compile_flags_if_supported(-fno-rtti)
endif()
-# Assert
-string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
+
+# 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.
- if (NOT MSVC)
- list(APPEND LIBCXX_COMPILE_FLAGS -D_DEBUG)
- endif()
- # On Release builds cmake automatically defines NDEBUG, so we
- # explicitly undefine it:
- if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
- list(APPEND LIBCXX_COMPILE_FLAGS -UNDEBUG)
- endif()
-else()
- if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
- list(APPEND LIBCXX_COMPILE_FLAGS -DNDEBUG)
- endif()
-endif()
-# Static library
-if (NOT LIBCXX_ENABLE_SHARED)
- list(APPEND LIBCXX_COMPILE_FLAGS -D_LIBCPP_BUILD_STATIC)
+ define_if_not(MSVC -D_DEBUG)
endif()
-if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
- if (LIBCXX_BUILD_32_BITS)
- message(STATUS "Building 32 bits executables and libraries.")
- list(APPEND LIBCXX_CXX_FLAGS "-m32")
- endif()
-elseif(LIBCXX_BUILD_32_BITS)
- message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.")
-endif()
-# This is the _ONLY_ place where add_definitions is called.
-if (MSVC)
- add_definitions(-D_CRT_SECURE_NO_WARNINGS)
-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)
-# LIBCXX_ENABLE_THREADS configuration
-if (NOT LIBCXX_ENABLE_THREADS)
- add_definitions(-D_LIBCPP_HAS_NO_THREADS)
- if (NOT LIBCXX_ENABLE_MONOTONIC_CLOCK)
- add_definitions(-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
- endif()
-# Ensure LIBCXX_ENABLE_MONOTONIC_CLOCK is set to ON.
-elseif(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()
+
+# 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)
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_FNO_OMIT_FRAME_POINTER_FLAG
- "-fno-omit-frame-pointer")
+ 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")
- append_if(LIBCXX_CXX_FLAGS LIBCXX_HAS_GLINE_TABLES_ONLY_FLAG
- "-gline-tables-only")
+ add_flags_if_supported("-gline-tables-only")
endif()
if (LLVM_USE_SANITIZER STREQUAL "Address")
- list(APPEND LIBCXX_CXX_FLAGS "-fsanitize=address")
+ add_flags("-fsanitize=address")
elseif (LLVM_USE_SANITIZER MATCHES "Memory(WithOrigins)?")
- list(APPEND LIBCXX_CXX_FLAGS "-fsanitize=memory")
+ add_flags(-fsanitize=memory)
if (LLVM_USE_SANITIZER STREQUAL "MemoryWithOrigins")
- list(APPEND LIBCXX_CXX_FLAGS "-fsanitize-memory-track-origins")
+ add_flags("-fsanitize-memory-track-origins")
endif()
elseif (LLVM_USE_SANITIZER STREQUAL "Undefined")
- list(APPEND LIBCXX_CXX_FLAGS
- "-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover")
+ add_flags("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all")
elseif (LLVM_USE_SANITIZER STREQUAL "Thread")
- list(APPEND LIBCXX_CXX_FLAGS "-fsanitize=thread")
+ add_flags(-fsanitize=thread)
else()
message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
endif()
- elseif(MSVC)
- message(WARNING "LLVM_USE_SANITIZER is not supported with MSVC")
+ elseif(LLVM_USE_SANITIZER AND MSVC)
+ message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.")
endif()
endif()
-
-append_if(LIBCXX_CXX_FLAGS LIBCXX_TARGET_TRIPLE
- "-target ${LIBCXX_TARGET_TRIPLE}")
-append_if(LIBCXX_CXX_FLAGS LIBCXX_SYSROOT "--sysroot ${LIBCXX_SYSROOT}")
-append_if(LIBCXX_CXX_FLAGS LIBCXX_GCC_TOOLCHAIN
- "-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}")
-
-string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_FLAGS}")
-
#===============================================================================
-# Setup Source Code
+# Setup Source Code And Tests
#===============================================================================
-
include_directories(include)
add_subdirectory(include)
-
-# Add source code. This also contains all of the logic for deciding linker flags
-# soname, etc...
add_subdirectory(lib)
-
-#===============================================================================
-# Setup Tests
-#===============================================================================
-
-add_subdirectory(test)
+if (LIBCXX_INCLUDE_TESTS)
+ add_subdirectory(test)
+endif()
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 41ca5d1..53352e4 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -14,7 +14,7 @@
University of Illinois/NCSA
Open Source License
-Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT
All rights reserved.
diff --git a/TODO.TXT b/TODO.TXT
new file mode 100644
index 0000000..513b863
--- /dev/null
+++ b/TODO.TXT
@@ -0,0 +1,49 @@
+This is meant to be a general place to list things that should be done "someday"
+
+ABI Related Tasks
+=================
+* Explicitly manage and verify symbols exported from the dylib.
+* Explore using namespaces for managing symbol visibility.
+* Introduce and document ABI versioning/evolution policy.
+
+CXX Runtime Library Tasks
+=========================
+* Cleanup #ifdef hell in sources files that supports the different ABI libraries.
+* Fix that CMake always link to /usr/lib/libc++abi.dylib on OS X.
+* Fix selection of ABI symbol list on OS X.
+* Have CMake generate linker scripts for libc++.so that it properly links the
+ runtime library.
+* Look into mirroring libsupc++'s typeinfo vtable layout when libsupc++/libstdc++
+ is used as the runtime library.
+* Audit libraries that CMake links into libc++. Are they all required?
+* Investigate and document interoperability between libc++ and libstdc++ on
+ linux. Do this for every supported c++ runtime library.
+
+Atomic Related Tasks
+====================
+* Support <atomic> in C++03 (needed for internal use).
+* Audit use of libatomic builtins in <atomic> with GCC.
+* future should use <atomic> for synchronization.
+* call_once should use <atomic> for synchronization.
+* Audit shared_ptr use of <atomic>
+
+Test Suite Tasks
+================
+* Get test suite passing in C++03.
+* Move all libc++ specific tests from test/std into test/libcxx.
+* Improve how LIT handles compiler warnings.
+* Improve the quality and portability of the locale test data.
+
+Misc Tasks
+==========
+* Find all sequences of >2 underscores and eradicate them.
+* run clang-tidy on libc++
+* Document the "conditionally-supported" bits of libc++
+* Look at basic_string's move assignment operator, re LWG 2063 and POCMA
+* libc++ is missing try_emplace
+* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)
+* Investigate the effect of using __decltype instead of __typeof__ to provide
+ decltype in C++03. What code could be broken by this change?
+* Convert failure tests to use Clang Verify.
+* Document support (or lack of) for C++11 libraries in C++03.
+* Document supported compilers.
diff --git a/cmake/Modules/CodeCoverage.cmake b/cmake/Modules/CodeCoverage.cmake
new file mode 100644
index 0000000..addd10a
--- /dev/null
+++ b/cmake/Modules/CodeCoverage.cmake
@@ -0,0 +1,36 @@
+find_program(CODE_COVERAGE_LCOV lcov)
+if (NOT CODE_COVERAGE_LCOV)
+ message(FATAL_ERROR "Cannot find lcov...")
+endif()
+
+find_program(CODE_COVERAGE_GENHTML genhtml)
+if (NOT CODE_COVERAGE_GENHTML)
+ message(FATAL_ERROR "Cannot find genhtml...")
+endif()
+
+set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage")
+
+function(setup_lcov_test_target_coverage target_name output_dir capture_dirs source_dirs)
+ file(MAKE_DIRECTORY ${output_dir})
+
+ set(CAPTURE_DIRS "")
+ foreach(cdir ${capture_dirs})
+ list(APPEND CAPTURE_DIRS "-d;${cdir}")
+ endforeach()
+
+ set(EXTRACT_DIRS "")
+ foreach(sdir ${source_dirs})
+ list(APPEND EXTRACT_DIRS "'${sdir}/*'")
+ endforeach()
+
+ message(STATUS "Capture Directories: ${CAPTURE_DIRS}")
+ message(STATUS "Extract Directories: ${EXTRACT_DIRS}")
+
+ add_custom_target(generate-lib${target_name}-coverage
+ COMMAND ${CODE_COVERAGE_LCOV} --capture ${CAPTURE_DIRS} -o test_coverage.info
+ COMMAND ${CODE_COVERAGE_LCOV} --extract test_coverage.info ${EXTRACT_DIRS} -o test_coverage.info
+ COMMAND ${CODE_COVERAGE_GENHTML} --demangle-cpp test_coverage.info -o test_coverage
+ COMMAND ${CMAKE_COMMAND} -E remove test_coverage.info
+ WORKING_DIRECTORY ${output_dir}
+ COMMENT "Generating coverage results")
+endfunction()
diff --git a/cmake/Modules/HandleLibCXXABI.cmake b/cmake/Modules/HandleLibCXXABI.cmake
index 960df9e..4224882 100644
--- a/cmake/Modules/HandleLibCXXABI.cmake
+++ b/cmake/Modules/HandleLibCXXABI.cmake
@@ -15,9 +15,9 @@
# abidirs : A list of relative paths to create under an include directory
# in the libc++ build directory.
#
-macro(setup_abi_lib abipathvar abidefines abilib abifiles abidirs)
+macro(setup_abi_lib abidefines abilib abifiles abidirs)
list(APPEND LIBCXX_COMPILE_FLAGS ${abidefines})
- set(${abipathvar} "${${abipathvar}}"
+ set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${LIBCXX_CXX_ABI_INCLUDE_PATHS}"
CACHE PATH
"Paths to C++ ABI header directories separated by ';'." FORCE
)
@@ -33,7 +33,7 @@
foreach(fpath ${LIBCXX_ABILIB_FILES})
set(found FALSE)
- foreach(incpath ${${abipathvar}})
+ foreach(incpath ${LIBCXX_CXX_ABI_INCLUDE_PATHS})
if (EXISTS "${incpath}/${fpath}")
set(found TRUE)
get_filename_component(dstdir ${fpath} PATH)
@@ -58,6 +58,21 @@
endmacro()
+# Setup the default options if LIBCXX_CXX_ABI is not specified.
+if (NOT LIBCXX_CXX_ABI)
+ if (NOT DEFINED LIBCXX_BUILT_STANDALONE AND
+ IS_DIRECTORY "${CMAKE_SOURCE_DIR}/projects/libcxxabi")
+ set(LIBCXX_CXX_ABI_LIBNAME "libcxxabi")
+ set(LIBCXX_CXX_ABI_INCLUDE_PATHS "${CMAKE_SOURCE_DIR}/projects/libcxxabi/include")
+ set(LIBCXX_CXX_ABI_INTREE 1)
+ else ()
+ set(LIBCXX_CXX_ABI_LIBNAME "none")
+ endif ()
+else ()
+ set(LIBCXX_CXX_ABI_LIBNAME "${LIBCXX_CXX_ABI}")
+endif ()
+
+# Configure based on the selected ABI library.
if ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libstdc++" OR
"${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libsupc++")
set(_LIBSUPCXX_INCLUDE_FILES
@@ -71,7 +86,7 @@
set(_LIBSUPCXX_DEFINES "")
set(_LIBSUPCXX_LIBNAME supc++)
endif()
- setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS"
+ setup_abi_lib(
"-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
"${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
)
@@ -88,11 +103,11 @@
# Assume c++abi is installed in the system, rely on -lc++abi link flag.
set(CXXABI_LIBNAME "c++abi")
endif()
- setup_abi_lib("LIBCXX_LIBCXXABI_INCLUDE_PATHS" ""
+ setup_abi_lib("-DLIBCXX_BUILDING_LIBCXXABI"
${CXXABI_LIBNAME} "cxxabi.h;__cxxabi_config.h" ""
)
elseif ("${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "libcxxrt")
- setup_abi_lib("LIBCXX_LIBCXXRT_INCLUDE_PATHS" "-DLIBCXXRT"
+ setup_abi_lib("-DLIBCXXRT"
"cxxrt" "cxxabi.h;unwind.h;unwind-arm.h;unwind-itanium.h" ""
)
elseif (NOT "${LIBCXX_CXX_ABI_LIBNAME}" STREQUAL "none")
diff --git a/cmake/Modules/HandleLibcxxFlags.cmake b/cmake/Modules/HandleLibcxxFlags.cmake
new file mode 100644
index 0000000..223b7b7
--- /dev/null
+++ b/cmake/Modules/HandleLibcxxFlags.cmake
@@ -0,0 +1,147 @@
+# HandleLibcxxFlags - A set of macros used to setup the flags used to compile
+# and link libc++. These macros add flags to the following CMake variables.
+# - LIBCXX_COMPILE_FLAGS: flags used to compile libc++
+# - LIBCXX_LINK_FLAGS: flags used to link libc++
+# - LIBCXX_LIBRARIES: libraries to link libc++ to.
+
+include(CheckCXXCompilerFlag)
+
+unset(add_flag_if_supported)
+
+# Mangle the name of a compiler flag into a valid CMake identifier.
+# Ex: --std=c++11 -> STD_EQ_CXX11
+macro(mangle_name str output)
+ string(STRIP "${str}" strippedStr)
+ string(REGEX REPLACE "^/" "" strippedStr "${strippedStr}")
+ string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}")
+ string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}")
+ string(REPLACE "-" "_" strippedStr "${strippedStr}")
+ string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}")
+ string(REPLACE "+" "X" strippedStr "${strippedStr}")
+ string(TOUPPER "${strippedStr}" ${output})
+endmacro()
+
+# Remove a list of flags from all CMake variables that affect compile flags.
+# This can be used to remove unwanted flags specified on the command line
+# or added in other parts of LLVM's cmake configuration.
+macro(remove_flags)
+ foreach(var ${ARGN})
+ string(REPLACE "${var}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REPLACE "${var}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+ string(REPLACE "${var}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
+ string(REPLACE "${var}" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+ string(REPLACE "${var}" "" CMAKE_SHARED_MODULE_FLAGS "${CMAKE_SHARED_MODULE_FLAGS}")
+ remove_definitions(${var})
+ endforeach()
+endmacro(remove_flags)
+
+# Add a macro definition if condition is true.
+macro(define_if condition def)
+ if (${condition})
+ add_definitions(${def})
+ endif()
+endmacro()
+
+# Add a macro definition if condition is not true.
+macro(define_if_not condition def)
+ if (NOT ${condition})
+ add_definitions(${def})
+ endif()
+endmacro()
+
+# Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and
+# 'LIBCXX_LINK_FLAGS'.
+macro(add_flags)
+ foreach(value ${ARGN})
+ list(APPEND LIBCXX_COMPILE_FLAGS ${value})
+ list(APPEND LIBCXX_LINK_FLAGS ${value})
+ endforeach()
+endmacro()
+
+# If the specified 'condition' is true then add a list of flags to both
+# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'.
+macro(add_flags_if condition)
+ if (${condition})
+ add_flags(${ARGN})
+ endif()
+endmacro()
+
+# Add each flag in the list to LIBCXX_COMPILE_FLAGS and LIBCXX_LINK_FLAGS
+# if that flag is supported by the current compiler.
+macro(add_flags_if_supported)
+ foreach(flag ${ARGN})
+ mangle_name("${flag}" flagname)
+ check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+ add_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+ endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBCXX_COMPILE_FLAGS'.
+macro(add_compile_flags)
+ foreach(f ${ARGN})
+ list(APPEND LIBCXX_COMPILE_FLAGS ${f})
+ endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBCXX_COMPILE_FLAGS'
+macro(add_compile_flags_if condition)
+ if (${condition})
+ add_compile_flags(${ARGN})
+ endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBCXX_COMPILE_FLAGS' if the
+# flag is supported by the C++ compiler.
+macro(add_compile_flags_if_supported)
+ foreach(flag ${ARGN})
+ mangle_name("${flag}" flagname)
+ check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+ add_compile_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+ endforeach()
+endmacro()
+
+# Add a list of flags to 'LIBCXX_LINK_FLAGS'.
+macro(add_link_flags)
+ foreach(f ${ARGN})
+ list(APPEND LIBCXX_LINK_FLAGS ${f})
+ endforeach()
+endmacro()
+
+# If 'condition' is true then add the specified list of flags to
+# 'LIBCXX_LINK_FLAGS'
+macro(add_link_flags_if condition)
+ if (${condition})
+ add_link_flags(${ARGN})
+ endif()
+endmacro()
+
+# For each specified flag, add that flag to 'LIBCXX_LINK_FLAGS' if the
+# flag is supported by the C++ compiler.
+macro(add_link_flags_if_supported)
+ foreach(flag ${ARGN})
+ mangle_name("${flag}" flagname)
+ check_cxx_compiler_flag("${flag}" "LIBCXX_SUPPORTS_${flagname}_FLAG")
+ add_link_flags_if(LIBCXX_SUPPORTS_${flagname}_FLAG ${flag})
+ endforeach()
+endmacro()
+
+# Add a list of libraries or link flags to 'LIBCXX_LIBRARIES'.
+macro(add_library_flags)
+ foreach(lib ${ARGN})
+ list(APPEND LIBCXX_LIBRARIES ${lib})
+ endforeach()
+endmacro()
+
+# if 'condition' is true then add the specified list of libraries and flags
+# to 'LIBCXX_LIBRARIES'.
+macro(add_library_flags_if condition)
+ if(${condition})
+ add_library_flags(${ARGN})
+ endif()
+endmacro()
+
+# Turn a comma separated CMake list into a space separated string.
+macro(split_list listname)
+ string(REPLACE ";" " " ${listname} "${${listname}}")
+endmacro()
diff --git a/cmake/Modules/HandleOutOfTreeLLVM.cmake b/cmake/Modules/HandleOutOfTreeLLVM.cmake
new file mode 100644
index 0000000..bf629a9
--- /dev/null
+++ b/cmake/Modules/HandleOutOfTreeLLVM.cmake
@@ -0,0 +1,96 @@
+macro(find_llvm_parts)
+# Rely on llvm-config.
+ set(CONFIG_OUTPUT)
+ find_program(LLVM_CONFIG "llvm-config")
+ if(DEFINED LLVM_PATH)
+ set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include")
+ set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree")
+ set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})
+ set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules")
+ elseif(LLVM_CONFIG)
+ message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}")
+ set(CONFIG_COMMAND ${LLVM_CONFIG}
+ "--includedir"
+ "--prefix"
+ "--src-root")
+ execute_process(
+ COMMAND ${CONFIG_COMMAND}
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE CONFIG_OUTPUT
+ )
+ if(NOT HAD_ERROR)
+ string(REGEX REPLACE
+ "[ \t]*[\r\n]+[ \t]*" ";"
+ CONFIG_OUTPUT ${CONFIG_OUTPUT})
+ else()
+ string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}")
+ message(STATUS "${CONFIG_COMMAND_STR}")
+ message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
+ endif()
+
+ list(GET CONFIG_OUTPUT 0 INCLUDE_DIR)
+ list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT)
+ list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR)
+
+ set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
+ set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
+ set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
+ set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/share/llvm/cmake")
+ else()
+ set(LLVM_FOUND OFF)
+ return()
+ endif()
+
+ if (NOT EXISTS ${LLVM_MAIN_SRC_DIR})
+ message(FATAL_ERROR "Not found: ${LLVM_MAIN_SRC_DIR}")
+ endif()
+
+ if(NOT EXISTS ${LLVM_CMAKE_PATH})
+ message(FATAL_ERROR "Not found: ${LLVM_CMAKE_PATH}")
+ endif()
+
+ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
+ list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+
+ set(LLVM_FOUND ON)
+endmacro(find_llvm_parts)
+
+
+if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+ set(LIBCXX_BUILT_STANDALONE 1)
+ message(STATUS "Configuring for standalone build.")
+
+ find_llvm_parts()
+
+ # LLVM Options --------------------------------------------------------------
+ include(FindPythonInterp)
+ if( NOT PYTHONINTERP_FOUND )
+ message(WARNING "Failed to find python interpreter. "
+ "The libc++ test suite will be disabled.")
+ set(LLVM_INCLUDE_TESTS OFF)
+ endif()
+
+ if (NOT DEFINED LLVM_INCLUDE_TESTS)
+ set(LLVM_INCLUDE_TESTS ${LLVM_FOUND})
+ endif()
+
+ # Required LIT Configuration ------------------------------------------------
+ # Define the default arguments to use with 'lit', and an option for the user
+ # to override.
+ set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported")
+ if (MSVC OR XCODE)
+ set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
+ endif()
+ set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
+
+ # Make sure we can use the console pool for recent cmake and ninja > 1.5
+ # Needed for add_lit_testsuite
+ if(CMAKE_VERSION VERSION_LESS 3.1.20141117)
+ set(cmake_3_2_USES_TERMINAL)
+ else()
+ set(cmake_3_2_USES_TERMINAL USES_TERMINAL)
+ endif()
+
+ # Add LLVM Functions --------------------------------------------------------
+ include(AddLLVM OPTIONAL)
+endif()
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 428d737..ace7aca 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -2,23 +2,7 @@
include(CheckCXXCompilerFlag)
# Check compiler flags
-check_cxx_compiler_flag(-std=c++11 LIBCXX_HAS_STDCXX11_FLAG)
-check_cxx_compiler_flag(-std=c++1y LIBCXX_HAS_STDCXX1Y_FLAG)
-check_cxx_compiler_flag(-fPIC LIBCXX_HAS_FPIC_FLAG)
-check_cxx_compiler_flag(-fno-omit-frame-pointer LIBCXX_HAS_FNO_OMIT_FRAME_POINTER_FLAG)
-check_cxx_compiler_flag(-nodefaultlibs LIBCXX_HAS_NODEFAULTLIBS_FLAG)
-check_cxx_compiler_flag(-nostdinc++ LIBCXX_HAS_NOSTDINCXX_FLAG)
-check_cxx_compiler_flag(-Wall LIBCXX_HAS_WALL_FLAG)
-check_cxx_compiler_flag(-W LIBCXX_HAS_W_FLAG)
-check_cxx_compiler_flag(-Wno-unused-parameter LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG)
-check_cxx_compiler_flag(-Wwrite-strings LIBCXX_HAS_WWRITE_STRINGS_FLAG)
-check_cxx_compiler_flag(-Wno-long-long LIBCXX_HAS_WNO_LONG_LONG_FLAG)
-check_cxx_compiler_flag(-pedantic LIBCXX_HAS_PEDANTIC_FLAG)
-check_cxx_compiler_flag(-Werror LIBCXX_HAS_WERROR_FLAG)
-check_cxx_compiler_flag(-Wno-error LIBCXX_HAS_WNO_ERROR_FLAG)
-check_cxx_compiler_flag(-fno-exceptions LIBCXX_HAS_FNO_EXCEPTIONS_FLAG)
-check_cxx_compiler_flag(-fno-rtti LIBCXX_HAS_FNO_RTTI_FLAG)
-check_cxx_compiler_flag(-gline-tables-only LIBCXX_HAS_GLINE_TABLES_ONLY_FLAG)
+
check_cxx_compiler_flag(/WX LIBCXX_HAS_WX_FLAG)
check_cxx_compiler_flag(/WX- LIBCXX_HAS_NO_WX_FLAG)
check_cxx_compiler_flag(/EHsc LIBCXX_HAS_EHSC_FLAG)
@@ -26,6 +10,7 @@
check_cxx_compiler_flag(/EHa- LIBCXX_HAS_NO_EHA_FLAG)
check_cxx_compiler_flag(/GR- LIBCXX_HAS_NO_GR_FLAG)
+
# Check libraries
check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
diff --git a/include/__config b/include/__config
index d89025f..600f0fb 100644
--- a/include/__config
+++ b/include/__config
@@ -17,13 +17,11 @@
#ifdef __GNUC__
#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
+#else
+#define _GNUC_VER 0
#endif
-#if !_WIN32
-#include <unistd.h>
-#endif
-
-#define _LIBCPP_VERSION 1101
+#define _LIBCPP_VERSION 3800
#define _LIBCPP_ABI_VERSION 1
@@ -32,6 +30,23 @@
#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
@@ -75,10 +90,8 @@
#ifdef _WIN32
# define _LIBCPP_LITTLE_ENDIAN 1
# define _LIBCPP_BIG_ENDIAN 0
-// Compiler intrinsics (GCC or MSVC)
-# if defined(__clang__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1400) \
- || (defined(__GNUC__) && _GNUC_VER > 403)
+// Compiler intrinsics (MSVC)
+#if defined(_MSC_VER) && _MSC_VER >= 1400
# define _LIBCPP_HAS_IS_BASE_OF
# endif
# if defined(_MSC_VER) && !defined(__clang__)
@@ -93,12 +106,6 @@
# endif
#endif // _WIN32
-#ifdef __linux__
-# if defined(__GNUC__) && _GNUC_VER >= 403
-# define _LIBCPP_HAS_IS_BASE_OF
-# endif
-#endif
-
#ifdef __sun__
# include <sys/isa_defs.h>
# ifdef _LITTLE_ENDIAN
@@ -110,12 +117,22 @@
# endif
#endif // __sun__
-#if defined(__native_client__)
+#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
-#endif // defined(__native_client__)
+#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>
@@ -172,10 +189,6 @@
#endif // _WIN32
-#ifndef __has_attribute
-#define __has_attribute(__x) 0
-#endif
-
#ifndef _LIBCPP_HIDDEN
#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden")))
#endif
@@ -308,6 +321,10 @@
# 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
@@ -326,6 +343,10 @@
#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
@@ -387,6 +408,11 @@
#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
@@ -405,6 +431,8 @@
// 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)
@@ -476,6 +504,7 @@
#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
@@ -518,6 +547,8 @@
#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
@@ -557,7 +588,12 @@
#endif // _LIBCPP_HAS_NO_STATIC_ASSERT
#ifdef _LIBCPP_HAS_NO_DECLTYPE
-#define decltype(x) __typeof__(x)
+// 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
@@ -578,14 +614,6 @@
#define _NOALIAS
#endif
-#ifndef __has_feature
-#define __has_feature(__x) 0
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(__x) 0
-#endif
-
#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__)
# define _LIBCPP_EXPLICIT explicit
#else
@@ -621,7 +649,7 @@
#endif
#ifndef _LIBCPP_EXTERN_TEMPLATE
-#define _LIBCPP_EXTERN_TEMPLATE(...)
+#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
#endif
#ifndef _LIBCPP_EXTERN_TEMPLATE2
@@ -632,10 +660,16 @@
#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63)
#endif
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
+#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
@@ -708,8 +742,29 @@
_LIBCPP_HAS_NO_THREADS is defined.
#endif
-#if defined(__ANDROID__)
+// 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/__debug b/include/__debug
index c151224..a21f9a8 100644
--- a/include/__debug
+++ b/include/__debug
@@ -22,7 +22,7 @@
# include <cstdio>
# include <cstddef>
# ifndef _LIBCPP_ASSERT
-# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::printf("%s\n", m), _VSTD::abort()))
+# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::fprintf(stderr, "%s\n", m), _VSTD::abort()))
# endif
#endif
diff --git a/include/__functional_03 b/include/__functional_03
index 157d6bf..56a8475 100644
--- a/include/__functional_03
+++ b/include/__functional_03
@@ -17,218 +17,7 @@
#pragma GCC system_header
#endif
-template <class _Tp>
-class __mem_fn
- : public __weak_result_type<_Tp>
-{
-public:
- // types
- typedef _Tp type;
-private:
- type __f_;
-
-public:
- _LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
-
- // invoke
-
- typename __invoke_return<type>::type
- operator() () const
- {
- return __invoke(__f_);
- }
-
- template <class _A0>
- typename __invoke_return0<type, _A0>::type
- operator() (_A0& __a0) const
- {
- return __invoke(__f_, __a0);
- }
-
- template <class _A0, class _A1>
- typename __invoke_return1<type, _A0, _A1>::type
- operator() (_A0& __a0, _A1& __a1) const
- {
- return __invoke(__f_, __a0, __a1);
- }
-
- template <class _A0, class _A1, class _A2>
- typename __invoke_return2<type, _A0, _A1, _A2>::type
- operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
- {
- return __invoke(__f_, __a0, __a1, __a2);
- }
-};
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp _Tp::*>
-mem_fn(_Rp _Tp::* __pm)
-{
- return __mem_fn<_Rp _Tp::*>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)()>
-mem_fn(_Rp (_Tp::* __pm)())
-{
- return __mem_fn<_Rp (_Tp::*)()>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0)>
-mem_fn(_Rp (_Tp::* __pm)(_A0))
-{
- return __mem_fn<_Rp (_Tp::*)(_A0)>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1)>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1))
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1)>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2))
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2)>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)() const>
-mem_fn(_Rp (_Tp::* __pm)() const)
-{
- return __mem_fn<_Rp (_Tp::*)() const>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0) const>
-mem_fn(_Rp (_Tp::* __pm)(_A0) const)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0) const>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1) const>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)() volatile>
-mem_fn(_Rp (_Tp::* __pm)() volatile)
-{
- return __mem_fn<_Rp (_Tp::*)() volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0) volatile)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) volatile)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) volatile)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) volatile>(__pm);
-}
-
-template<class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)() const volatile>
-mem_fn(_Rp (_Tp::* __pm)() const volatile)
-{
- return __mem_fn<_Rp (_Tp::*)() const volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0) const volatile)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0) const volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1) const volatile)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1) const volatile>(__pm);
-}
-
-template<class _Rp, class _Tp, class _A0, class _A1, class _A2>
-inline _LIBCPP_INLINE_VISIBILITY
-__mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>
-mem_fn(_Rp (_Tp::* __pm)(_A0, _A1, _A2) const volatile)
-{
- return __mem_fn<_Rp (_Tp::*)(_A0, _A1, _A2) const volatile>(__pm);
-}
-
-// bad_function_call
-
-class _LIBCPP_EXCEPTION_ABI bad_function_call
- : public exception
-{
-};
-
-template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined
-
-namespace __function
-{
-
-template<class _Fp>
-struct __maybe_derive_from_unary_function
-{
-};
-
-template<class _Rp, class _A1>
-struct __maybe_derive_from_unary_function<_Rp(_A1)>
- : public unary_function<_A1, _Rp>
-{
-};
-
-template<class _Fp>
-struct __maybe_derive_from_binary_function
-{
-};
-
-template<class _Rp, class _A1, class _A2>
-struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
-{
-};
+namespace __function {
template<class _Fp> class __base;
@@ -333,7 +122,8 @@
__base<_Rp()>*
__func<_Fp, _Alloc, _Rp()>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -359,7 +149,8 @@
void
__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
@@ -417,7 +208,8 @@
__base<_Rp(_A0)>*
__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -443,7 +235,8 @@
void
__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
@@ -501,7 +294,8 @@
__base<_Rp(_A0, _A1)>*
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -527,7 +321,8 @@
void
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
@@ -585,7 +380,8 @@
__base<_Rp(_A0, _A1, _A2)>*
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -611,7 +407,8 @@
void
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
@@ -794,17 +591,11 @@
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<_FF>
-#else
- rebind_alloc<_FF>::other
-#endif
- _Ap;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -831,6 +622,7 @@
else if (__f_)
__f_->destroy_deallocate();
__f_ = 0;
+ return *this;
}
template<class _Rp>
@@ -1096,17 +888,11 @@
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<_FF>
-#else
- rebind_alloc<_FF>::other
-#endif
- _Ap;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1133,6 +919,7 @@
else if (__f_)
__f_->destroy_deallocate();
__f_ = 0;
+ return *this;
}
template<class _Rp, class _A0>
@@ -1398,17 +1185,11 @@
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<_FF>
-#else
- rebind_alloc<_FF>::other
-#endif
- _Ap;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1435,6 +1216,7 @@
else if (__f_)
__f_->destroy_deallocate();
__f_ = 0;
+ return *this;
}
template<class _Rp, class _A0, class _A1>
@@ -1700,17 +1482,11 @@
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<_FF>
-#else
- rebind_alloc<_FF>::other
-#endif
- _Ap;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1737,6 +1513,7 @@
else if (__f_)
__f_->destroy_deallocate();
__f_ = 0;
+ return *this;
}
template<class _Rp, class _A0, class _A1, class _A2>
@@ -1868,272 +1645,4 @@
swap(function<_Fp>& __x, function<_Fp>& __y)
{return __x.swap(__y);}
-template<class _Tp> struct __is_bind_expression : public false_type {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
- : public __is_bind_expression<typename remove_cv<_Tp>::type> {};
-
-template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {};
-template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder
- : public __is_placeholder<typename remove_cv<_Tp>::type> {};
-
-namespace placeholders
-{
-
-template <int _Np> struct __ph {};
-
-extern __ph<1> _1;
-extern __ph<2> _2;
-extern __ph<3> _3;
-extern __ph<4> _4;
-extern __ph<5> _5;
-extern __ph<6> _6;
-extern __ph<7> _7;
-extern __ph<8> _8;
-extern __ph<9> _9;
-extern __ph<10> _10;
-
-} // placeholders
-
-template<int _Np>
-struct __is_placeholder<placeholders::__ph<_Np> >
- : public integral_constant<int, _Np> {};
-
-template <class _Tp, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-_Tp&
-__mu(reference_wrapper<_Tp> __t, _Uj&)
-{
- return __t.get();
-}
-/*
-template <bool _IsBindExpr, class _Ti, class ..._Uj>
-struct __mu_return1 {};
-
-template <class _Ti, class ..._Uj>
-struct __mu_return1<true, _Ti, _Uj...>
-{
- typedef typename result_of<_Ti(_Uj...)>::type type;
-};
-
-template <class _Ti, class ..._Uj, size_t ..._Indx>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __mu_return1<true, _Ti, _Uj...>::type
-__mu_expand(_Ti& __ti, tuple<_Uj...>&& __uj, __tuple_indices<_Indx...>)
-{
- __ti(_VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj))...);
-}
-
-template <class _Ti, class ..._Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- is_bind_expression<_Ti>::value,
- typename __mu_return1<is_bind_expression<_Ti>::value, _Ti, _Uj...>::type
->::type
-__mu(_Ti& __ti, tuple<_Uj...>& __uj)
-{
- typedef typename __make_tuple_indices<sizeof...(_Uj)>::type __indices;
- return __mu_expand(__ti, __uj, __indices());
-}
-
-template <bool IsPh, class _Ti, class _Uj>
-struct __mu_return2 {};
-
-template <class _Ti, class _Uj>
-struct __mu_return2<true, _Ti, _Uj>
-{
- typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _Uj>::type type;
-};
-
-template <class _Ti, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- 0 < is_placeholder<_Ti>::value,
- typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type
->::type
-__mu(_Ti&, _Uj& __uj)
-{
- const size_t _Indx = is_placeholder<_Ti>::value - 1;
- // compiler bug workaround
- typename tuple_element<_Indx, _Uj>::type __t = _VSTD::get<_Indx>(__uj);
- return __t;
-// return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj));
-}
-
-template <class _Ti, class _Uj>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
- !is_bind_expression<_Ti>::value &&
- is_placeholder<_Ti>::value == 0 &&
- !__is_reference_wrapper<_Ti>::value,
- _Ti&
->::type
-__mu(_Ti& __ti, _Uj& __uj)
-{
- return __ti;
-}
-
-template <class _Ti, bool IsBindEx, bool IsPh, class _TupleUj>
-struct ____mu_return;
-
-template <class _Ti, class ..._Uj>
-struct ____mu_return<_Ti, true, false, tuple<_Uj...> >
-{
- typedef typename result_of<_Ti(_Uj...)>::type type;
-};
-
-template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, false, true, _TupleUj>
-{
- typedef typename tuple_element<is_placeholder<_Ti>::value - 1,
- _TupleUj>::type&& type;
-};
-
-template <class _Ti, class _TupleUj>
-struct ____mu_return<_Ti, false, false, _TupleUj>
-{
- typedef _Ti& type;
-};
-
-template <class _Ti, class _TupleUj>
-struct __mu_return
- : public ____mu_return<_Ti,
- is_bind_expression<_Ti>::value,
- 0 < is_placeholder<_Ti>::value,
- _TupleUj>
-{
-};
-
-template <class _Ti, class _TupleUj>
-struct __mu_return<reference_wrapper<_Ti>, _TupleUj>
-{
- typedef _Ti& type;
-};
-
-template <class _Fp, class _BoundArgs, class _TupleUj>
-struct __bind_return;
-
-template <class _Fp, class ..._BoundArgs, class _TupleUj>
-struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
-{
- typedef typename __ref_return
- <
- _Fp&,
- typename __mu_return
- <
- _BoundArgs,
- _TupleUj
- >::type...
- >::type type;
-};
-
-template <class _Fp, class ..._BoundArgs, class _TupleUj>
-struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
-{
- typedef typename __ref_return
- <
- _Fp&,
- typename __mu_return
- <
- const _BoundArgs,
- _TupleUj
- >::type...
- >::type type;
-};
-
-template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args>
-inline _LIBCPP_INLINE_VISIBILITY
-typename __bind_return<_Fp, _BoundArgs, _Args>::type
-__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
- _Args&& __args)
-{
- return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);
-}
-
-template<class _Fp, class ..._BoundArgs>
-class __bind
-{
- _Fp __f_;
- tuple<_BoundArgs...> __bound_args_;
-
- typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices;
-public:
- template <class _Gp, class ..._BA>
- explicit __bind(_Gp&& __f, _BA&& ...__bound_args)
- : __f_(_VSTD::forward<_Gp>(__f)),
- __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
-
- template <class ..._Args>
- typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
- operator()(_Args&& ...__args)
- {
- // compiler bug workaround
- return __apply_functor(__f_, __bound_args_, __indices(),
- tuple<_Args&&...>(__args...));
- }
-
- template <class ..._Args>
- typename __bind_return<_Fp, tuple<_BoundArgs...>, tuple<_Args&&...> >::type
- operator()(_Args&& ...__args) const
- {
- return __apply_functor(__f_, __bound_args_, __indices(),
- tuple<_Args&&...>(__args...));
- }
-};
-
-template<class _Fp, class ..._BoundArgs>
-struct __is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {};
-
-template<class _Rp, class _Fp, class ..._BoundArgs>
-class __bind_r
- : public __bind<_Fp, _BoundArgs...>
-{
- typedef __bind<_Fp, _BoundArgs...> base;
-public:
- typedef _Rp result_type;
-
- template <class _Gp, class ..._BA>
- explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
- : base(_VSTD::forward<_Gp>(__f),
- _VSTD::forward<_BA>(__bound_args)...) {}
-
- template <class ..._Args>
- result_type
- operator()(_Args&& ...__args)
- {
- return base::operator()(_VSTD::forward<_Args>(__args)...);
- }
-
- template <class ..._Args>
- result_type
- operator()(_Args&& ...__args) const
- {
- return base::operator()(_VSTD::forward<_Args>(__args)...);
- }
-};
-
-template<class _Rp, class _Fp, class ..._BoundArgs>
-struct __is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {};
-
-template<class _Fp, class ..._BoundArgs>
-inline _LIBCPP_INLINE_VISIBILITY
-__bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
-bind(_Fp&& __f, _BoundArgs&&... __bound_args)
-{
- typedef __bind<typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
- return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
-}
-
-template<class _Rp, class _Fp, class ..._BoundArgs>
-inline _LIBCPP_INLINE_VISIBILITY
-__bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...>
-bind(_Fp&& __f, _BoundArgs&&... __bound_args)
-{
- typedef __bind_r<_Rp, typename decay<_Fp>::type, typename decay<_BoundArgs>::type...> type;
- return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
-}
-*/
-
#endif // _LIBCPP_FUNCTIONAL_03
diff --git a/include/__functional_base b/include/__functional_base
index 09424bc..3ff2e35 100644
--- a/include/__functional_base
+++ b/include/__functional_base
@@ -127,11 +127,6 @@
}
#endif
-#ifdef _LIBCPP_HAS_NO_VARIADICS
-
-#include <__functional_base_03>
-
-#else // _LIBCPP_HAS_NO_VARIADICS
// __weak_result_type
@@ -314,6 +309,8 @@
{
};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
// 3 or more arguments
template <class _Rp, class _A1, class _A2, class _A3, class ..._A4>
@@ -358,8 +355,12 @@
typedef _Rp result_type;
};
+#endif // _LIBCPP_HAS_NO_VARIADICS
+
// __invoke
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
// bullets 1 and 2
template <class _Fp, class _A0, class ..._Args,
@@ -414,31 +415,79 @@
{
return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...);
}
-
template <class _Tp, class ..._Args>
struct __invoke_return
{
typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
};
+#else // _LIBCPP_HAS_NO_VARIADICS
+
+#include <__functional_base_03>
+
+#endif // _LIBCPP_HAS_NO_VARIADICS
+
+
template <class _Ret>
struct __invoke_void_return_wrapper
{
+#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class ..._Args>
- static _Ret __call(_Args&&... __args)
- {
+ static _Ret __call(_Args&&... __args) {
return __invoke(_VSTD::forward<_Args>(__args)...);
}
+#else
+ template <class _Fn>
+ static _Ret __call(_Fn __f) {
+ return __invoke(__f);
+ }
+
+ template <class _Fn, class _A0>
+ static _Ret __call(_Fn __f, _A0& __a0) {
+ return __invoke(__f, __a0);
+ }
+
+ template <class _Fn, class _A0, class _A1>
+ static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
+ return __invoke(__f, __a0, __a1);
+ }
+
+ template <class _Fn, class _A0, class _A1, class _A2>
+ static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
+ return __invoke(__f, __a0, __a1, __a2);
+ }
+#endif
};
template <>
struct __invoke_void_return_wrapper<void>
{
+#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class ..._Args>
- static void __call(_Args&&... __args)
- {
+ static void __call(_Args&&... __args) {
__invoke(_VSTD::forward<_Args>(__args)...);
}
+#else
+ template <class _Fn>
+ static void __call(_Fn __f) {
+ __invoke(__f);
+ }
+
+ template <class _Fn, class _A0>
+ static void __call(_Fn __f, _A0& __a0) {
+ __invoke(__f, __a0);
+ }
+
+ template <class _Fn, class _A0, class _A1>
+ static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
+ __invoke(__f, __a0, __a1);
+ }
+
+ template <class _Fn, class _A0, class _A1, class _A2>
+ static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
+ __invoke(__f, __a0, __a1, __a2);
+ }
+#endif
};
template <class _Tp>
@@ -463,6 +512,7 @@
_LIBCPP_INLINE_VISIBILITY operator type& () const _NOEXCEPT {return *__f_;}
_LIBCPP_INLINE_VISIBILITY type& get() const _NOEXCEPT {return *__f_;}
+#ifndef _LIBCPP_HAS_NO_VARIADICS
// invoke
template <class... _ArgTypes>
_LIBCPP_INLINE_VISIBILITY
@@ -471,6 +521,39 @@
{
return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
}
+#else
+
+ _LIBCPP_INLINE_VISIBILITY
+ typename __invoke_return<type>::type
+ operator() () const
+ {
+ return __invoke(get());
+ }
+
+ template <class _A0>
+ _LIBCPP_INLINE_VISIBILITY
+ typename __invoke_return0<type&, _A0>::type
+ operator() (_A0& __a0) const
+ {
+ return __invoke<type&, _A0>(get(), __a0);
+ }
+
+ template <class _A0, class _A1>
+ _LIBCPP_INLINE_VISIBILITY
+ typename __invoke_return1<type&, _A0, _A1>::type
+ operator() (_A0& __a0, _A1& __a1) const
+ {
+ return __invoke<type&, _A0, _A1>(get(), __a0, __a1);
+ }
+
+ template <class _A0, class _A1, class _A2>
+ _LIBCPP_INLINE_VISIBILITY
+ typename __invoke_return2<type&, _A0, _A1, _A2>::type
+ operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
+ {
+ return __invoke<type&, _A0, _A1, _A2>(get(), __a0, __a1, __a2);
+ }
+#endif // _LIBCPP_HAS_NO_VARIADICS
};
template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
@@ -510,6 +593,7 @@
return cref(__t.get());
}
+#ifndef _LIBCPP_HAS_NO_VARIADICS
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
diff --git a/include/__functional_base_03 b/include/__functional_base_03
index 6550277..0a7ff62 100644
--- a/include/__functional_base_03
+++ b/include/__functional_base_03
@@ -13,404 +13,7 @@
// manual variadic expansion for <functional>
-// __weak_result_type
-
-template <class _Tp>
-struct __derives_from_unary_function
-{
-private:
- struct __two {char __lx; char __lxx;};
- static __two __test(...);
- template <class _Ap, class _Rp>
- static unary_function<_Ap, _Rp>
- __test(const volatile unary_function<_Ap, _Rp>*);
-public:
- static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
- typedef decltype(__test((_Tp*)0)) type;
-};
-
-template <class _Tp>
-struct __derives_from_binary_function
-{
-private:
- struct __two {char __lx; char __lxx;};
- static __two __test(...);
- template <class _A1, class _A2, class _Rp>
- static binary_function<_A1, _A2, _Rp>
- __test(const volatile binary_function<_A1, _A2, _Rp>*);
-public:
- static const bool value = !is_same<decltype(__test((_Tp*)0)), __two>::value;
- typedef decltype(__test((_Tp*)0)) type;
-};
-
-template <class _Tp, bool = __derives_from_unary_function<_Tp>::value>
-struct __maybe_derive_from_unary_function // bool is true
- : public __derives_from_unary_function<_Tp>::type
-{
-};
-
-template <class _Tp>
-struct __maybe_derive_from_unary_function<_Tp, false>
-{
-};
-
-template <class _Tp, bool = __derives_from_binary_function<_Tp>::value>
-struct __maybe_derive_from_binary_function // bool is true
- : public __derives_from_binary_function<_Tp>::type
-{
-};
-
-template <class _Tp>
-struct __maybe_derive_from_binary_function<_Tp, false>
-{
-};
-
-template <class _Tp, bool = __has_result_type<_Tp>::value>
-struct __weak_result_type_imp // bool is true
- : public __maybe_derive_from_unary_function<_Tp>,
- public __maybe_derive_from_binary_function<_Tp>
-{
- typedef typename _Tp::result_type result_type;
-};
-
-template <class _Tp>
-struct __weak_result_type_imp<_Tp, false>
- : public __maybe_derive_from_unary_function<_Tp>,
- public __maybe_derive_from_binary_function<_Tp>
-{
-};
-
-template <class _Tp>
-struct __weak_result_type
- : public __weak_result_type_imp<typename remove_reference<_Tp>::type>
-{
-};
-
-// 0 argument case
-
-template <class _Rp>
-struct __weak_result_type<_Rp ()>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp>
-struct __weak_result_type<_Rp (&)()>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp>
-struct __weak_result_type<_Rp (*)()>
-{
- typedef _Rp result_type;
-};
-
-// 1 argument case
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (_A1)>
- : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (&)(_A1)>
- : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _A1>
-struct __weak_result_type<_Rp (*)(_A1)>
- : public unary_function<_A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)()>
- : public unary_function<_Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() const>
- : public unary_function<const _Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() volatile>
- : public unary_function<volatile _Cp*, _Rp>
-{
-};
-
-template <class _Rp, class _Cp>
-struct __weak_result_type<_Rp (_Cp::*)() const volatile>
- : public unary_function<const volatile _Cp*, _Rp>
-{
-};
-
-// 2 argument case
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (*)(_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _A1, class _A2>
-struct __weak_result_type<_Rp (&)(_A1, _A2)>
- : public binary_function<_A1, _A2, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1)>
- : public binary_function<_Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) const>
- : public binary_function<const _Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile>
- : public binary_function<volatile _Cp*, _A1, _Rp>
-{
-};
-
-template <class _Rp, class _Cp, class _A1>
-struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile>
- : public binary_function<const volatile _Cp*, _A1, _Rp>
-{
-};
-
-// 3 or more arguments
-
-template <class _Rp, class _A1, class _A2, class _A3>
-struct __weak_result_type<_Rp (_A1, _A2, _A3)>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp, class _A1, class _A2, class _A3>
-struct __weak_result_type<_Rp (&)(_A1, _A2, _A3)>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp, class _A1, class _A2, class _A3>
-struct __weak_result_type<_Rp (*)(_A1, _A2, _A3)>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2)>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2) const>
-{
- typedef _Rp result_type;
-};
-
-template <class _Rp, class _Cp, class _A1, class _A2>
-struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2) volatile>
-{
- typedef _Rp result_type;
-};
-
// __invoke
-
-// __ref_return0
-//
-// template <class _Tp, bool _HasResultType>
-// struct ________ref_return0 // _HasResultType is true
-// {
-// typedef typename _Tp::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ________ref_return0<_Tp, false>
-// {
-// typedef void type;
-// };
-//
-// template <class _Tp, bool _IsClass>
-// struct ____ref_return0 // _IsClass is true
-// : public ________ref_return0<_Tp, __has_result_type<typename remove_cv<_Tp>::type>::value>
-// {
-// };
-//
-// template <class _Tp, bool _HasResultType>
-// struct ______ref_return0 // _HasResultType is true
-// {
-// typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ______ref_return0<_Tp, false> // pointer to member data
-// {
-// typedef void type;
-// };
-//
-// template <class _Tp>
-// struct ____ref_return0<_Tp, false>
-// : public ______ref_return0<typename remove_cv<_Tp>::type,
-// __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value>
-// {
-// };
-//
-// template <class _Tp>
-// struct __ref_return0
-// : public ____ref_return0<typename remove_reference<_Tp>::type,
-// is_class<typename remove_reference<_Tp>::type>::value>
-// {
-// };
-//
-// __ref_return1
-//
-// template <class _Tp, bool _IsClass, class _A0>
-// struct ____ref_return1 // _IsClass is true
-// {
-// typedef typename result_of<_Tp(_A0)>::type type;
-// };
-//
-// template <class _Tp, bool _HasResultType, class _A0>
-// struct ______ref_return1 // _HasResultType is true
-// {
-// typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp, class _A0, bool>
-// struct __ref_return1_member_data1;
-//
-// template <class _Rp, class _Cp, class _A0>
-// struct __ref_return1_member_data1<_Rp _Cp::*, _A0, true>
-// {
-// typedef typename __apply_cv<_A0, _Rp>::type& type;
-// };
-//
-// template <class _Rp, class _Cp, class _A0>
-// struct __ref_return1_member_data1<_Rp _Cp::*, _A0, false>
-// {
-// static _A0 __a;
-// typedef typename __apply_cv<decltype(*__a), _Rp>::type& type;
-// };
-//
-// template <class _Tp, class _A0>
-// struct __ref_return1_member_data;
-//
-// template <class _Rp, class _Cp, class _A0>
-// struct __ref_return1_member_data<_Rp _Cp::*, _A0>
-// : public __ref_return1_member_data1<_Rp _Cp::*, _A0,
-// is_same<typename remove_cv<_Cp>::type,
-// typename remove_cv<typename remove_reference<_A0>::type>::type>::value>
-// {
-// };
-//
-// template <class _Tp, class _A0>
-// struct ______ref_return1<_Tp, false, _A0> // pointer to member data
-// : public __ref_return1_member_data<typename remove_cv<_Tp>::type, _A0>
-// {
-// };
-//
-// template <class _Tp, class _A0>
-// struct ____ref_return1<_Tp, false, _A0>
-// : public ______ref_return1<typename remove_cv<_Tp>::type,
-// __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0>
-// {
-// };
-//
-// template <class _Tp, class _A0>
-// struct __ref_return1
-// : public ____ref_return1<typename remove_reference<_Tp>::type,
-// is_class<typename remove_reference<_Tp>::type>::value, _A0>
-// {
-// };
-//
-// __ref_return2
-//
-// template <class _Tp, bool _IsClass, class _A0, class _A1>
-// struct ____ref_return2 // _IsClass is true
-// {
-// typedef typename result_of<_Tp(_A0, _A1)>::type type;
-// };
-//
-// template <class _Tp, bool _HasResultType, class _A0, class _A1>
-// struct ______ref_return2 // _HasResultType is true
-// {
-// typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ______ref_return2<_Tp, false, class _A0, class _A1> // pointer to member data
-// {
-// static_assert(sizeof(_Tp) == 0, "An attempt has been made to `call` a pointer"
-// " to member data with too many arguments.");
-// };
-//
-// template <class _Tp, class _A0, class _A1>
-// struct ____ref_return2<_Tp, false, _A0, _A1>
-// : public ______ref_return2<typename remove_cv<_Tp>::type,
-// __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0, _A1>
-// {
-// };
-//
-// template <class _Tp, class _A0, class _A1>
-// struct __ref_return2
-// : public ____ref_return2<typename remove_reference<_Tp>::type,
-// is_class<typename remove_reference<_Tp>::type>::value, _A0, _A1>
-// {
-// };
-//
-// __ref_return3
-//
-// template <class _Tp, bool _IsClass, class _A0, class _A1, class _A2>
-// struct ____ref_return3 // _IsClass is true
-// {
-// typedef typename result_of<_Tp(_A0, _A1, _A2)>::type type;
-// };
-//
-// template <class _Tp, bool _HasResultType, class _A0, class _A1, class _A2>
-// struct ______ref_return3 // _HasResultType is true
-// {
-// typedef typename __callable_type<_Tp>::result_type type;
-// };
-//
-// template <class _Tp>
-// struct ______ref_return3<_Tp, false, class _A0, class _A1, class _A2> // pointer to member data
-// {
-// static_assert(sizeof(_Tp) == 0, "An attempt has been made to `call` a pointer"
-// " to member data with too many arguments.");
-// };
-//
-// template <class _Tp, class _A0, class _A1, class _A2>
-// struct ____ref_return3<_Tp, false, _A0, _A1, _A2>
-// : public ______ref_return3<typename remove_cv<_Tp>::type,
-// __has_result_type<__callable_type<typename remove_cv<_Tp>::type> >::value, _A0, _A1, _A2>
-// {
-// };
-//
-// template <class _Tp, class _A0, class _A1, class _A2>
-// struct __ref_return3
-// : public ____ref_return3<typename remove_reference<_Tp>::type,
-// is_class<typename remove_reference<_Tp>::type>::value, _A0, _A1, _A2>
-// {
-// };
-
// first bullet
template <class _Rp, class _Tp, class _T1>
@@ -805,32 +408,15 @@
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
+ is_member_object_pointer<_Rp _Tp::*>::value &&
is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
- typename __apply_cv<_T1, _Rp>::type&
->::type
+ __apply_cv<_T1, _Rp>
+>::type::type&
__invoke(_Rp _Tp::* __f, _T1& __t1)
{
return __t1.*__f;
}
-template <class _Rp, class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-__invoke(_Rp _Tp::*)
-{
-}
-
-// template <class _Dp, class _Rp, class _Tp, class _T1>
-// inline _LIBCPP_INLINE_VISIBILITY
-// typename enable_if
-// <
-// is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-// typename __ref_return1<_Rp _Tp::*, _T1>::type
-// >::type
-// __invoke(_Rp _Tp::* __f, _T1& __t1)
-// {
-// return __t1.*__f;
-// }
// forth bullet
@@ -842,114 +428,54 @@
template <class _T1, class _Rp>
struct __4th_helper<_T1, _Rp, true>
{
- typedef typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Rp>::type type;
+ typedef typename __apply_cv<decltype(*_VSTD::declval<_T1&>()), _Rp>::type type;
};
template <class _Rp, class _Tp, class _T1>
inline _LIBCPP_INLINE_VISIBILITY
typename __4th_helper<_T1, _Rp,
- !is_base_of<_Tp,
- typename remove_reference<_T1>::type
- >::value
- >::type&
+ is_member_object_pointer<_Rp _Tp::*>::value &&
+ !is_base_of<_Tp, typename remove_reference<_T1>::type>::value
+>::type&
__invoke(_Rp _Tp::* __f, _T1& __t1)
{
return (*__t1).*__f;
}
-// template <class _Dp, class _Rp, class _Tp, class _T1>
-// inline _LIBCPP_INLINE_VISIBILITY
-// typename enable_if
-// <
-// !is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-// typename __ref_return1<_Rp _Tp::*, _T1>::type
-// >::type
-// __invoke(_Rp _Tp::* __f, _T1 __t1)
-// {
-// return (*__t1).*__f;
-// }
-
// fifth bullet
template <class _Fp>
inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()())
-__invoke(_Fp __f)
+decltype(_VSTD::declval<_Fp&>()())
+__invoke(_Fp& __f)
{
return __f();
}
template <class _Fp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>()))
-__invoke(_Fp __f, _A0& __a0)
+decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))
+__invoke(_Fp& __f, _A0& __a0)
{
return __f(__a0);
}
template <class _Fp, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>()))
-__invoke(_Fp __f, _A0& __a0, _A1& __a1)
+decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>()))
+__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
{
return __f(__a0, __a1);
}
template <class _Fp, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
-__invoke(_Fp __f, _A0& __a0, _A1& __a1, _A2& __a2)
+decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>()))
+__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
{
return __f(__a0, __a1, __a2);
}
-// template <class _Rp, class _Fp>
-// inline _LIBCPP_INLINE_VISIBILITY
-// _Rp
-// __invoke(_Fp& __f)
-// {
-// return __f();
-// }
-//
-// template <class _Rp, class _Fp, class _A0>
-// inline _LIBCPP_INLINE_VISIBILITY
-// typename enable_if
-// <
-// !is_member_pointer<_Fp>::value,
-// _Rp
-// >::type
-// __invoke(_Fp& __f, _A0& __a0)
-// {
-// return __f(__a0);
-// }
-//
-// template <class _Rp, class _Fp, class _A0, class _A1>
-// inline _LIBCPP_INLINE_VISIBILITY
-// _Rp
-// __invoke(_Fp& __f, _A0& __a0, _A1& __a1)
-// {
-// return __f(__a0, __a1);
-// }
-//
-// template <class _Rp, class _Fp, class _A0, class _A1, class _A2>
-// inline _LIBCPP_INLINE_VISIBILITY
-// _Rp
-// __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
-// {
-// return __f(__a0, __a1, __a2);
-// }
-
-template <class _Tp>
-struct __has_type
-{
-private:
- struct __two {char __lx; char __lxx;};
- template <class _Up> static __two __test(...);
- template <class _Up> static char __test(typename _Up::type* = 0);
-public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
-
template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
struct __invoke_return
{
@@ -959,23 +485,23 @@
template <class _Fp>
struct __invoke_return<_Fp, false>
{
- typedef decltype(__invoke(_VSTD::declval<_Fp>())) type;
+ typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
};
-template <class _Tp, class _A0>
+template <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value>
struct __invoke_return0
{
- typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>())) type;
+ typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
};
template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0>
+struct __invoke_return0<_Rp _Tp::*, _A0, true>
{
typedef typename __apply_cv<_A0, _Rp>::type& type;
};
template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0*>
+struct __invoke_return0<_Rp _Tp::*, _A0*, true>
{
typedef typename __apply_cv<_A0, _Rp>::type& type;
};
@@ -983,162 +509,16 @@
template <class _Tp, class _A0, class _A1>
struct __invoke_return1
{
- typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
- _VSTD::declval<_A1>())) type;
+ typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
+ _VSTD::declval<_A1&>())) type;
};
template <class _Tp, class _A0, class _A1, class _A2>
struct __invoke_return2
{
- typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
- _VSTD::declval<_A1>(),
- _VSTD::declval<_A2>())) type;
+ typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
+ _VSTD::declval<_A1&>(),
+ _VSTD::declval<_A2&>())) type;
};
-template <class _Ret>
-struct __invoke_void_return_wrapper
-{
- template <class _Fn>
- static _Ret __call(_Fn __f)
- {
- return __invoke(__f);
- }
-
- template <class _Fn, class _A0>
- static _Ret __call(_Fn __f, _A0& __a0)
- {
- return __invoke(__f, __a0);
- }
-
- template <class _Fn, class _A0, class _A1>
- static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1)
- {
- return __invoke(__f, __a0, __a1);
- }
-
- template <class _Fn, class _A0, class _A1, class _A2>
- static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2)
- {
- return __invoke(__f, __a0, __a1, __a2);
- }
-};
-
-
-template <>
-struct __invoke_void_return_wrapper<void>
-{
- template <class _Fn>
- static void __call(_Fn __f)
- {
- __invoke(__f);
- }
-
- template <class _Fn, class _A0>
- static void __call(_Fn __f, _A0& __a0)
- {
- __invoke(__f, __a0);
- }
-
- template <class _Fn, class _A0, class _A1>
- static void __call(_Fn __f, _A0& __a0, _A1& __a1)
- {
- __invoke(__f, __a0, __a1);
- }
-
- template <class _Fn, class _A0, class _A1, class _A2>
- static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2)
- {
- __invoke(__f, __a0, __a1, __a2);
- }
-};
-
-template <class _Tp>
-class _LIBCPP_TYPE_VIS_ONLY reference_wrapper
- : public __weak_result_type<_Tp>
-{
-public:
- // types
- typedef _Tp type;
-private:
- type* __f_;
-
-public:
- // construct/copy/destroy
- _LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) : __f_(&__f) {}
-
- // access
- _LIBCPP_INLINE_VISIBILITY operator type& () const {return *__f_;}
- _LIBCPP_INLINE_VISIBILITY type& get() const {return *__f_;}
-
- // invoke
-
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return<type&>::type
- operator() () const
- {
- return __invoke(get());
- }
-
- template <class _A0>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return0<type&, _A0>::type
- operator() (_A0& __a0) const
- {
- return __invoke<type&, _A0>(get(), __a0);
- }
-
- template <class _A0, class _A1>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return1<type&, _A0, _A1>::type
- operator() (_A0& __a0, _A1& __a1) const
- {
- return __invoke<type&, _A0, _A1>(get(), __a0, __a1);
- }
-
- template <class _A0, class _A1, class _A2>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return2<type&, _A0, _A1, _A2>::type
- operator() (_A0& __a0, _A1& __a1, _A2& __a2) const
- {
- return __invoke<type&, _A0, _A1, _A2>(get(), __a0, __a1, __a2);
- }
-};
-
-template <class _Tp> struct __is_reference_wrapper_impl : public false_type {};
-template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {};
-template <class _Tp> struct __is_reference_wrapper
- : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {};
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<_Tp>
-ref(_Tp& __t)
-{
- return reference_wrapper<_Tp>(__t);
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<_Tp>
-ref(reference_wrapper<_Tp> __t)
-{
- return ref(__t.get());
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<const _Tp>
-cref(const _Tp& __t)
-{
- return reference_wrapper<const _Tp>(__t);
-}
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-reference_wrapper<const _Tp>
-cref(reference_wrapper<_Tp> __t)
-{
- return cref(__t.get());
-}
-
#endif // _LIBCPP_FUNCTIONAL_BASE_03
diff --git a/include/__hash_table b/include/__hash_table
index 71cf5fb..ec20e10 100644
--- a/include/__hash_table
+++ b/include/__hash_table
@@ -85,8 +85,6 @@
template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator;
template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator;
template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator;
-template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
- class _LIBCPP_TYPE_VIS_ONLY unordered_map;
template <class _NodePtr>
class _LIBCPP_TYPE_VIS_ONLY __hash_iterator
@@ -777,13 +775,7 @@
public:
// Create __node
typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__node>
-#else
- rebind_alloc<__node>::other
-#endif
- __node_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
typedef allocator_traits<__node_allocator> __node_traits;
typedef typename __node_traits::pointer __node_pointer;
typedef typename __node_traits::pointer __node_const_pointer;
@@ -798,13 +790,7 @@
private:
- typedef typename __node_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__node_pointer>
-#else
- rebind_alloc<__node_pointer>::other
-#endif
- __pointer_allocator;
+ typedef typename __rebind_alloc_helper<__node_traits, __node_pointer>::type __pointer_allocator;
typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list;
typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits;
@@ -910,11 +896,21 @@
iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ template <class _ValueTp>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> __insert_unique_value(_ValueTp&& __x);
+#else
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> __insert_unique_value(const value_type& __x);
+#endif
+
pair<iterator, bool> __insert_unique(const value_type& __x);
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ pair<iterator, bool> __insert_unique(value_type&& __x);
template <class _Pp>
- pair<iterator, bool> __insert_unique(_Pp&& __x);
+ pair<iterator, bool> __insert_unique(_Pp&& __x);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -988,13 +984,17 @@
__equal_range_multi(const _Key& __k) const;
void swap(__hash_table& __u)
+#if _LIBCPP_STD_VER <= 11
_NOEXCEPT_(
- (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__pointer_allocator>::value) &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value);
+ __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
+ && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__pointer_allocator>::value)
+ && (!__node_traits::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__node_allocator>::value)
+ );
+#else
+ _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value);
+#endif
_LIBCPP_INLINE_VISIBILITY
size_type max_bucket_count() const _NOEXCEPT
@@ -1122,38 +1122,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {}
- template <class _Ap>
- _LIBCPP_INLINE_VISIBILITY
- static
- void
- __swap_alloc(_Ap& __x, _Ap& __y)
- _NOEXCEPT_(
- !allocator_traits<_Ap>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<_Ap>::value)
- {
- __swap_alloc(__x, __y,
- integral_constant<bool,
- allocator_traits<_Ap>::propagate_on_container_swap::value
- >());
- }
-
- template <class _Ap>
- _LIBCPP_INLINE_VISIBILITY
- static
- void
- __swap_alloc(_Ap& __x, _Ap& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<_Ap>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
-
- template <class _Ap>
- _LIBCPP_INLINE_VISIBILITY
- static
- void
- __swap_alloc(_Ap&, _Ap&, false_type) _NOEXCEPT {}
-
void __deallocate(__node_pointer __np) _NOEXCEPT;
__node_pointer __detach() _NOEXCEPT;
@@ -1753,6 +1721,26 @@
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x)
{
+ return __insert_unique_value(__x);
+}
+
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <class _ValueTp>
+_LIBCPP_INLINE_VISIBILITY
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(_ValueTp&& __x)
+#else
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type& __x)
+#endif
+{
+#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
+ typedef const value_type& _ValueTp;
+#endif
size_t __hash = hash_function()(__x);
size_type __bc = bucket_count();
bool __inserted = false;
@@ -1774,7 +1762,7 @@
}
}
{
- __node_holder __h = __construct_node(__x, __hash);
+ __node_holder __h = __construct_node(_VSTD::forward<_ValueTp>(__x), __hash);
if (size()+1 > __bc * max_load_factor() || __bc == 0)
{
rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc),
@@ -1858,6 +1846,13 @@
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class _Hash, class _Equal, class _Alloc>
+pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(value_type&& __x)
+{
+ return __insert_unique_value(_VSTD::move(__x));
+}
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _Pp>
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x)
@@ -2358,13 +2353,17 @@
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
+#if _LIBCPP_STD_VER <= 11
_NOEXCEPT_(
- (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__pointer_allocator>::value) &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value)
+ __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value
+ && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__pointer_allocator>::value)
+ && (!__node_traits::propagate_on_container_swap::value
+ || __is_nothrow_swappable<__node_allocator>::value)
+ )
+#else
+ _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value)
+#endif
{
{
__node_pointer_pointer __npp = __bucket_list_.release();
@@ -2372,9 +2371,9 @@
__u.__bucket_list_.reset(__npp);
}
_VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size());
- __swap_alloc(__bucket_list_.get_deleter().__alloc(),
+ __swap_allocator(__bucket_list_.get_deleter().__alloc(),
__u.__bucket_list_.get_deleter().__alloc());
- __swap_alloc(__node_alloc(), __u.__node_alloc());
+ __swap_allocator(__node_alloc(), __u.__node_alloc());
_VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_);
__p2_.swap(__u.__p2_);
__p3_.swap(__u.__p3_);
diff --git a/include/__locale b/include/__locale
index 625d0f8..1989558 100644
--- a/include/__locale
+++ b/include/__locale
@@ -353,6 +353,7 @@
static const mask punct = _PUNCT;
static const mask xdigit = _HEX;
static const mask blank = _BLANK;
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
# ifdef __APPLE__
typedef __uint32_t mask;
@@ -401,6 +402,9 @@
static const mask punct = _P;
static const mask xdigit = _X | _N;
static const mask blank = _B;
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
+# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
#else
typedef unsigned long mask;
static const mask space = 1<<0;
diff --git a/include/__split_buffer b/include/__split_buffer
index 1d529cb..727b1b6 100644
--- a/include/__split_buffer
+++ b/include/__split_buffer
@@ -156,25 +156,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
- __is_nothrow_swappable<__alloc_rr>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__alloc_rr>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__alloc_rr&, __alloc_rr&, false_type) _NOEXCEPT
- {}
};
template <class _Tp, class _Allocator>
@@ -431,7 +412,7 @@
_VSTD::swap(__begin_, __x.__begin_);
_VSTD::swap(__end_, __x.__end_);
_VSTD::swap(__end_cap(), __x.__end_cap());
- __swap_alloc(__alloc(), __x.__alloc());
+ __swap_allocator(__alloc(), __x.__alloc());
}
template <class _Tp, class _Allocator>
diff --git a/include/__std_stream b/include/__std_stream
index 5403ada..f867cd2 100644
--- a/include/__std_stream
+++ b/include/__std_stream
@@ -276,7 +276,6 @@
codecvt_base::result __r;
char_type* pbase = &__1buf;
char_type* pptr = pbase + 1;
- char_type* epptr = pptr;
do
{
const char_type* __e;
diff --git a/include/__tree b/include/__tree
index 2aa9c1f..3ad5794 100644
--- a/include/__tree
+++ b/include/__tree
@@ -28,14 +28,6 @@
class _LIBCPP_TYPE_VIS_ONLY __tree_iterator;
template <class _Tp, class _ConstNodePtr, class _DiffType>
class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
-template <class _Key, class _Tp, class _Compare, class _Allocator>
- class _LIBCPP_TYPE_VIS_ONLY map;
-template <class _Key, class _Tp, class _Compare, class _Allocator>
- class _LIBCPP_TYPE_VIS_ONLY multimap;
-template <class _Key, class _Compare, class _Allocator>
- class _LIBCPP_TYPE_VIS_ONLY set;
-template <class _Key, class _Compare, class _Allocator>
- class _LIBCPP_TYPE_VIS_ONLY multiset;
/*
@@ -810,13 +802,7 @@
typedef __tree_node<value_type, __void_pointer> __node;
typedef __tree_node_base<__void_pointer> __node_base;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__node>
-#else
- rebind_alloc<__node>::other
-#endif
- __node_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
typedef allocator_traits<__node_allocator> __node_traits;
typedef typename __node_traits::pointer __node_pointer;
typedef typename __node_traits::pointer __node_const_pointer;
@@ -940,9 +926,12 @@
void swap(__tree& __t)
_NOEXCEPT_(
- __is_nothrow_swappable<value_compare>::value &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value));
+ __is_nothrow_swappable<value_compare>::value
+#if _LIBCPP_STD_VER <= 11
+ && (!__node_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<__node_allocator>::value)
+#endif
+ );
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_VARIADICS
@@ -1110,25 +1099,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
- _NOEXCEPT_(
- !__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __node_traits::propagate_on_container_swap::value>());}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
- _NOEXCEPT
- {}
-
__node_pointer __detach();
static __node_pointer __detach(__node_pointer);
@@ -1148,8 +1118,8 @@
template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a)
- : __pair1_(__node_allocator(__a)),
- __begin_node_(__node_pointer()),
+ : __begin_node_(__node_pointer()),
+ __pair1_(__node_allocator(__a)),
__pair3_(0)
{
__begin_node() = __end_node();
@@ -1158,8 +1128,8 @@
template <class _Tp, class _Compare, class _Allocator>
__tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp,
const allocator_type& __a)
- : __pair1_(__node_allocator(__a)),
- __begin_node_(__node_pointer()),
+ : __begin_node_(__node_pointer()),
+ __pair1_(__node_allocator(__a)),
__pair3_(0, __comp)
{
__begin_node() = __end_node();
@@ -1466,15 +1436,18 @@
template <class _Tp, class _Compare, class _Allocator>
void
__tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
- _NOEXCEPT_(
- __is_nothrow_swappable<value_compare>::value &&
- (!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value))
+ _NOEXCEPT_(
+ __is_nothrow_swappable<value_compare>::value
+#if _LIBCPP_STD_VER <= 11
+ && (!__node_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<__node_allocator>::value)
+#endif
+ )
{
using _VSTD::swap;
swap(__begin_node_, __t.__begin_node_);
swap(__pair1_.first(), __t.__pair1_.first());
- __swap_alloc(__node_alloc(), __t.__node_alloc());
+ __swap_allocator(__node_alloc(), __t.__node_alloc());
__pair3_.swap(__t.__pair3_);
if (size() == 0)
__begin_node() = __end_node();
@@ -2085,7 +2058,6 @@
typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const
{
- typedef pair<const_iterator, const_iterator> _Pp;
__node_const_pointer __result = __end_node();
__node_const_pointer __rt = __root();
while (__rt != nullptr)
diff --git a/include/__tuple b/include/__tuple
index bffb95c..2837ce7 100644
--- a/include/__tuple
+++ b/include/__tuple
@@ -19,40 +19,9 @@
#pragma GCC system_header
#endif
-#ifdef _LIBCPP_HAS_NO_VARIADICS
-
-#include <__tuple_03>
-
-#else // _LIBCPP_HAS_NO_VARIADICS
_LIBCPP_BEGIN_NAMESPACE_STD
-// __lazy_and
-
-template <bool _Last, class ..._Preds>
-struct __lazy_and_impl;
-
-template <class ..._Preds>
-struct __lazy_and_impl<false, _Preds...> : false_type {};
-
-template <>
-struct __lazy_and_impl<true> : true_type {};
-
-template <class _Pred>
-struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
-
-template <class _Hp, class ..._Tp>
-struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
-
-template <class _P1, class ..._Pr>
-struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
-
-// __lazy_not
-
-template <class _Pred>
-struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
-
-
template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
template <class _Tp>
@@ -90,19 +59,18 @@
typedef typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type;
};
-template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
-template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
-template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
-
template <class _Tp> struct __tuple_like : false_type {};
template <class _Tp> struct __tuple_like<const _Tp> : public __tuple_like<_Tp> {};
template <class _Tp> struct __tuple_like<volatile _Tp> : public __tuple_like<_Tp> {};
template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_like<_Tp> {};
+// tuple specializations
+
+#if !defined(_LIBCPP_HAS_NO_VARIADICS)
+template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple;
+
template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {};
-template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
-template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
template <size_t _Ip, class ..._Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -118,6 +86,13 @@
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
typename tuple_element<_Ip, tuple<_Tp...> >::type&&
get(tuple<_Tp...>&&) _NOEXCEPT;
+#endif
+
+// pair specializations
+
+template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair;
+
+template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {};
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -129,10 +104,18 @@
const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
get(const pair<_T1, _T2>&) _NOEXCEPT;
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
get(pair<_T1, _T2>&&) _NOEXCEPT;
+#endif
+
+// array specializations
+
+template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY array;
+
+template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : true_type {};
template <size_t _Ip, class _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -144,10 +127,39 @@
const _Tp&
get(const array<_Tp, _Size>&) _NOEXCEPT;
+#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <size_t _Ip, class _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp&&
get(array<_Tp, _Size>&&) _NOEXCEPT;
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_VARIADICS)
+
+// __lazy_and
+
+template <bool _Last, class ..._Preds>
+struct __lazy_and_impl;
+
+template <class ..._Preds>
+struct __lazy_and_impl<false, _Preds...> : false_type {};
+
+template <>
+struct __lazy_and_impl<true> : true_type {};
+
+template <class _Pred>
+struct __lazy_and_impl<true, _Pred> : integral_constant<bool, _Pred::type::value> {};
+
+template <class _Hp, class ..._Tp>
+struct __lazy_and_impl<true, _Hp, _Tp...> : __lazy_and_impl<_Hp::type::value, _Tp...> {};
+
+template <class _P1, class ..._Pr>
+struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {};
+
+// __lazy_not
+
+template <class _Pred>
+struct __lazy_not : integral_constant<bool, !_Pred::type::value> {};
// __make_tuple_indices
@@ -354,8 +366,8 @@
tuple_size<_Up>::value, _Tp, _Up>
{};
-_LIBCPP_END_NAMESPACE_STD
-
#endif // _LIBCPP_HAS_NO_VARIADICS
+_LIBCPP_END_NAMESPACE_STD
+
#endif // _LIBCPP___TUPLE
diff --git a/include/__tuple_03 b/include/__tuple_03
deleted file mode 100644
index b91c2cd..0000000
--- a/include/__tuple_03
+++ /dev/null
@@ -1,27 +0,0 @@
-// -*- 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___TUPLE_03
-#define _LIBCPP___TUPLE_03
-
-#include <__config>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size;
-template <size_t _Ip, class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_element;
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TUPLE_03
diff --git a/include/algorithm b/include/algorithm
index 415059d..c1635fc 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -521,11 +521,11 @@
template <class ForwardIterator>
ForwardIterator
- min_element(ForwardIterator first, ForwardIterator last);
+ min_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14
template <class ForwardIterator, class Compare>
ForwardIterator
- min_element(ForwardIterator first, ForwardIterator last, Compare comp);
+ min_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14
template <class T>
const T&
@@ -545,11 +545,11 @@
template <class ForwardIterator>
ForwardIterator
- max_element(ForwardIterator first, ForwardIterator last);
+ max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14
template <class ForwardIterator, class Compare>
ForwardIterator
- max_element(ForwardIterator first, ForwardIterator last, Compare comp);
+ max_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14
template <class T>
const T&
@@ -569,11 +569,11 @@
template<class ForwardIterator>
pair<ForwardIterator, ForwardIterator>
- minmax_element(ForwardIterator first, ForwardIterator last);
+ minmax_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14
template<class ForwardIterator, class Compare>
pair<ForwardIterator, ForwardIterator>
- minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);
+ minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); // constexpr in C++14
template<class T>
pair<const T&, const T&>
@@ -1763,7 +1763,8 @@
__copy(_Tp* __first, _Tp* __last, _Up* __result)
{
const size_t __n = static_cast<size_t>(__last - __first);
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ if (__n > 0)
+ _VSTD::memmove(__result, __first, __n * sizeof(_Up));
return __result + __n;
}
@@ -1798,8 +1799,11 @@
__copy_backward(_Tp* __first, _Tp* __last, _Up* __result)
{
const size_t __n = static_cast<size_t>(__last - __first);
- __result -= __n;
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ if (__n > 0)
+ {
+ __result -= __n;
+ _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ }
return __result;
}
@@ -1896,7 +1900,8 @@
__move(_Tp* __first, _Tp* __last, _Up* __result)
{
const size_t __n = static_cast<size_t>(__last - __first);
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ if (__n > 0)
+ _VSTD::memmove(__result, __first, __n * sizeof(_Up));
return __result + __n;
}
@@ -1931,8 +1936,11 @@
__move_backward(_Tp* __first, _Tp* __last, _Up* __result)
{
const size_t __n = static_cast<size_t>(__last - __first);
- __result -= __n;
- _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ if (__n > 0)
+ {
+ __result -= __n;
+ _VSTD::memmove(__result, __first, __n * sizeof(_Up));
+ }
return __result;
}
@@ -2544,7 +2552,7 @@
template <class _ForwardIterator, class _Compare>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
-__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
if (__first != __last)
{
@@ -2556,20 +2564,12 @@
return __first;
}
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
- return __min_element(__first, __last, __comp);
-}
-
template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
min_element(_ForwardIterator __first, _ForwardIterator __last)
{
- return __min_element(__first, __last,
+ return _VSTD::min_element(__first, __last,
__less<typename iterator_traits<_ForwardIterator>::value_type>());
}
@@ -2598,7 +2598,7 @@
_Tp
min(initializer_list<_Tp> __t, _Compare __comp)
{
- return *__min_element(__t.begin(), __t.end(), __comp);
+ return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
}
template<class _Tp>
@@ -2606,7 +2606,7 @@
_Tp
min(initializer_list<_Tp> __t)
{
- return *__min_element(__t.begin(), __t.end(), __less<_Tp>());
+ return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>());
}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2616,7 +2616,7 @@
template <class _ForwardIterator, class _Compare>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
-__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
+max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
if (__first != __last)
{
@@ -2629,20 +2629,12 @@
}
-template <class _ForwardIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY
-_ForwardIterator
-max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
-{
- return __max_element(__first, __last, __comp);
-}
-
template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_ForwardIterator
max_element(_ForwardIterator __first, _ForwardIterator __last)
{
- return __max_element(__first, __last,
+ return _VSTD::max_element(__first, __last,
__less<typename iterator_traits<_ForwardIterator>::value_type>());
}
@@ -2671,7 +2663,7 @@
_Tp
max(initializer_list<_Tp> __t, _Compare __comp)
{
- return *__max_element(__t.begin(), __t.end(), __comp);
+ return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
}
template<class _Tp>
@@ -2679,7 +2671,7 @@
_Tp
max(initializer_list<_Tp> __t)
{
- return *__max_element(__t.begin(), __t.end(), __less<_Tp>());
+ return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>());
}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -2687,6 +2679,7 @@
// minmax_element
template <class _ForwardIterator, class _Compare>
+_LIBCPP_CONSTEXPR_AFTER_CXX11
std::pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{
@@ -2734,7 +2727,7 @@
}
template <class _ForwardIterator>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
std::pair<_ForwardIterator, _ForwardIterator>
minmax_element(_ForwardIterator __first, _ForwardIterator __last)
{
@@ -3044,7 +3037,7 @@
if (_Rp == 0)
return static_cast<result_type>(_Eng(__g, _Dt)());
size_t __w = _Dt - __clz(_Rp) - 1;
- if ((_Rp & (_UIntType(~0) >> (_Dt - __w))) != 0)
+ if ((_Rp & (std::numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0)
++__w;
_Eng __e(__g, __w);
_UIntType __u;
@@ -4368,6 +4361,34 @@
// inplace_merge
+template <class _Compare, class _InputIterator1, class _InputIterator2,
+ class _OutputIterator>
+void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,
+ _InputIterator2 __first2, _InputIterator2 __last2,
+ _OutputIterator __result, _Compare __comp)
+{
+ for (; __first1 != __last1; ++__result)
+ {
+ if (__first2 == __last2)
+ {
+ _VSTD::move(__first1, __last1, __result);
+ return;
+ }
+
+ if (__comp(*__first2, *__first1))
+ {
+ *__result = _VSTD::move(*__first2);
+ ++__first2;
+ }
+ else
+ {
+ *__result = _VSTD::move(*__first1);
+ ++__first1;
+ }
+ }
+ // __first2 through __last2 are already in the right spot.
+}
+
template <class _Compare, class _BidirectionalIterator>
void
__buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
@@ -4383,11 +4404,7 @@
value_type* __p = __buff;
for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p)
::new(__p) value_type(_VSTD::move(*__i));
- __merge<_Compare>(move_iterator<value_type*>(__buff),
- move_iterator<value_type*>(__p),
- move_iterator<_BidirectionalIterator>(__middle),
- move_iterator<_BidirectionalIterator>(__last),
- __first, __comp);
+ __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp);
}
else
{
@@ -4396,9 +4413,9 @@
::new(__p) value_type(_VSTD::move(*__i));
typedef reverse_iterator<_BidirectionalIterator> _RBi;
typedef reverse_iterator<value_type*> _Rv;
- __merge(move_iterator<_RBi>(_RBi(__middle)), move_iterator<_RBi>(_RBi(__first)),
- move_iterator<_Rv>(_Rv(__p)), move_iterator<_Rv>(_Rv(__buff)),
- _RBi(__last), __negate<_Compare>(__comp));
+ __half_inplace_merge(_Rv(__p), _Rv(__buff),
+ _RBi(__middle), _RBi(__first),
+ _RBi(__last), __negate<_Compare>(__comp));
}
}
diff --git a/include/array b/include/array
index d37075d..2e02a43 100644
--- a/include/array
+++ b/include/array
@@ -288,10 +288,6 @@
class _LIBCPP_TYPE_VIS_ONLY tuple_size<array<_Tp, _Size> >
: public integral_constant<size_t, _Size> {};
-template <class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_size<const array<_Tp, _Size> >
- : public integral_constant<size_t, _Size> {};
-
template <size_t _Ip, class _Tp, size_t _Size>
class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, array<_Tp, _Size> >
{
@@ -300,13 +296,6 @@
};
template <size_t _Ip, class _Tp, size_t _Size>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, const array<_Tp, _Size> >
-{
-public:
- typedef const _Tp type;
-};
-
-template <size_t _Ip, class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
_Tp&
get(array<_Tp, _Size>& __a) _NOEXCEPT
diff --git a/include/atomic b/include/atomic
index 0427a91..97a998d 100644
--- a/include/atomic
+++ b/include/atomic
@@ -554,7 +554,8 @@
template <typename _Tp>
struct __gcc_atomic_t {
__gcc_atomic_t() _NOEXCEPT {}
- explicit __gcc_atomic_t(_Tp value) _NOEXCEPT : __a_value(value) {}
+ _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT
+ : __a_value(value) {}
_Tp __a_value;
};
#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>
@@ -633,10 +634,6 @@
__atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));
}
-static inline bool __c11_atomic_is_lock_free(size_t __size) {
- return __atomic_is_lock_free(__size, 0);
-}
-
template <typename _Tp>
static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val,
memory_order __order) {
@@ -827,10 +824,16 @@
_LIBCPP_INLINE_VISIBILITY
bool is_lock_free() const volatile _NOEXCEPT
- {return __c11_atomic_is_lock_free(sizeof(_Tp));}
+ {
+#if __has_feature(cxx_atomic)
+ return __c11_atomic_is_lock_free(sizeof(_Tp));
+#else
+ return __atomic_is_lock_free(sizeof(_Tp), 0);
+#endif
+ }
_LIBCPP_INLINE_VISIBILITY
bool is_lock_free() const _NOEXCEPT
- {return __c11_atomic_is_lock_free(sizeof(_Tp));}
+ {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
_LIBCPP_INLINE_VISIBILITY
void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
{__c11_atomic_store(&__a_, __d, __m);}
diff --git a/include/cinttypes b/include/cinttypes
index 786692b..cfd763c 100644
--- a/include/cinttypes
+++ b/include/cinttypes
@@ -247,7 +247,9 @@
using::imaxdiv_t;
+#undef imaxabs
using::imaxabs;
+#undef imaxdiv
using::imaxdiv;
using::strtoimax;
using::strtoumax;
diff --git a/include/clocale b/include/clocale
index f8b8f0d..05fa9c6 100644
--- a/include/clocale
+++ b/include/clocale
@@ -45,7 +45,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD
using ::lconv;
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
using ::setlocale;
+#endif
using ::localeconv;
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/cmath b/include/cmath
index b340b4d..5f9aaed 100644
--- a/include/cmath
+++ b/include/cmath
@@ -654,6 +654,10 @@
// abs
+#if defined(__sun__)
+using ::abs;
+#endif
+
#if !defined(_AIX) && !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY
float
diff --git a/include/cstdio b/include/cstdio
index 37814ef..d8ba6c2 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -144,30 +144,20 @@
using ::fpos_t;
using ::size_t;
-using ::remove;
-using ::rename;
-using ::tmpfile;
-using ::tmpnam;
using ::fclose;
using ::fflush;
-using ::fopen;
-using ::freopen;
using ::setbuf;
using ::setvbuf;
using ::fprintf;
using ::fscanf;
-using ::printf;
-using ::scanf;
using ::snprintf;
using ::sprintf;
using ::sscanf;
#ifndef _LIBCPP_MSVCRT
using ::vfprintf;
using ::vfscanf;
-using ::vscanf;
using ::vsscanf;
#endif // _LIBCPP_MSVCRT
-using ::vprintf;
using ::vsnprintf;
using ::vsprintf;
using ::fgetc;
@@ -175,13 +165,7 @@
using ::fputc;
using ::fputs;
using ::getc;
-using ::getchar;
-#if _LIBCPP_STD_VER <= 11
-using ::gets;
-#endif
using ::putc;
-using ::putchar;
-using ::puts;
using ::ungetc;
using ::fread;
using ::fwrite;
@@ -195,6 +179,31 @@
using ::ferror;
using ::perror;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+using ::fopen;
+using ::freopen;
+using ::remove;
+using ::rename;
+using ::tmpfile;
+using ::tmpnam;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDIN
+using ::getchar;
+#if _LIBCPP_STD_VER <= 11
+using ::gets;
+#endif
+using ::scanf;
+using ::vscanf;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+using ::printf;
+using ::putchar;
+using ::puts;
+using ::vprintf;
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_CSTDIO
diff --git a/include/cstdlib b/include/cstdlib
index 152b891..55e15c8 100644
--- a/include/cstdlib
+++ b/include/cstdlib
@@ -131,19 +131,27 @@
using ::system;
using ::bsearch;
using ::qsort;
+#undef abs
using ::abs;
+#undef labs
using ::labs;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
+#undef llabs
using ::llabs;
#endif // _LIBCPP_HAS_NO_LONG_LONG
+#undef div
using ::div;
+#undef ldiv
using ::ldiv;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
+#undef lldiv
using ::lldiv;
#endif // _LIBCPP_HAS_NO_LONG_LONG
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
using ::mblen;
using ::mbtowc;
using ::wctomb;
+#endif
using ::mbstowcs;
using ::wcstombs;
#ifdef _LIBCPP_HAS_QUICK_EXIT
diff --git a/include/cstring b/include/cstring
index 21c9155..d60b992 100644
--- a/include/cstring
+++ b/include/cstring
@@ -102,7 +102,9 @@
inline _LIBCPP_INLINE_VISIBILITY char* strstr( char* __s1, const char* __s2) {return ::strstr(__s1, __s2);}
#endif
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
using ::strtok;
+#endif
using ::memset;
using ::strerror;
using ::strlen;
diff --git a/include/ctime b/include/ctime
index fc4eb26..da9e329 100644
--- a/include/ctime
+++ b/include/ctime
@@ -61,10 +61,12 @@
using ::difftime;
using ::mktime;
using ::time;
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
using ::asctime;
using ::ctime;
using ::gmtime;
using ::localtime;
+#endif
using ::strftime;
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/cwchar b/include/cwchar
index 9f51587..797a177 100644
--- a/include/cwchar
+++ b/include/cwchar
@@ -126,24 +126,18 @@
using ::swprintf;
using ::vfwprintf;
using ::vswprintf;
-using ::vwprintf;
#ifndef _LIBCPP_MSVCRT
using ::swscanf;
using ::vfwscanf;
using ::vswscanf;
-using ::vwscanf;
#endif // _LIBCPP_MSVCRT
-using ::wprintf;
-using ::wscanf;
using ::fgetwc;
using ::fgetws;
using ::fputwc;
using ::fputws;
using ::fwide;
using ::getwc;
-using ::getwchar;
using ::putwc;
-using ::putwchar;
using ::ungetwc;
using ::wcstod;
#ifndef _LIBCPP_MSVCRT
@@ -212,6 +206,20 @@
using ::mbsrtowcs;
using ::wcsrtombs;
+#ifndef _LIBCPP_HAS_NO_STDIN
+using ::getwchar;
+#ifndef _LIBCPP_MSVCRT
+using ::vwscanf;
+#endif // _LIBCPP_MSVCRT
+using ::wscanf;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+using ::putwchar;
+using ::vwprintf;
+using ::wprintf;
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_CWCHAR
diff --git a/include/deque b/include/deque
index 6b419c5..87ff8bf 100644
--- a/include/deque
+++ b/include/deque
@@ -124,8 +124,7 @@
iterator erase(const_iterator p);
iterator erase(const_iterator f, const_iterator l);
void swap(deque& c)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
void clear() noexcept;
};
@@ -912,22 +911,10 @@
static const difference_type __block_size = sizeof(value_type) < 256 ? 4096 / sizeof(value_type) : 16;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<pointer>
-#else
- rebind_alloc<pointer>::other
-#endif
- __pointer_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, pointer>::type __pointer_allocator;
typedef allocator_traits<__pointer_allocator> __map_traits;
typedef typename __map_traits::pointer __map_pointer;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<const_pointer>
-#else
- rebind_alloc<const_pointer>::other
-#endif
- __const_pointer_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type __const_pointer_allocator;
typedef typename allocator_traits<__const_pointer_allocator>::const_pointer __map_const_pointer;
typedef __split_buffer<pointer, __pointer_allocator> __map;
@@ -966,8 +953,12 @@
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
void swap(__deque_base& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
protected:
void clear() _NOEXCEPT;
@@ -1003,26 +994,6 @@
_LIBCPP_INLINE_VISIBILITY
void __move_assign_alloc(__deque_base&, false_type) _NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type&, allocator_type&, false_type)
- _NOEXCEPT
- {}
};
template <class _Tp, class _Allocator>
@@ -1146,13 +1117,17 @@
template <class _Tp, class _Allocator>
void
__deque_base<_Tp, _Allocator>::swap(__deque_base& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
__map_.swap(__c.__map_);
_VSTD::swap(__start_, __c.__start_);
_VSTD::swap(size(), __c.size());
- __swap_alloc(__alloc(), __c.__alloc());
+ __swap_allocator(__alloc(), __c.__alloc());
}
template <class _Tp, class _Allocator>
@@ -1354,8 +1329,12 @@
iterator erase(const_iterator __f, const_iterator __l);
void swap(deque& __c)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);
+#endif
void clear() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -2050,7 +2029,6 @@
if (__n > __front_spare())
__add_front_capacity(__n - __front_spare());
// __n <= __front_spare()
- size_type __old_n = __n;
iterator __old_begin = __base::begin();
iterator __i = __old_begin;
if (__n > __pos)
@@ -2075,7 +2053,6 @@
if (__n > __back_capacity)
__add_back_capacity(__n - __back_capacity);
// __n <= __back_capacity
- size_type __old_n = __n;
iterator __old_end = __base::end();
iterator __i = __old_end;
size_type __de = __base::size() - __pos;
@@ -2140,7 +2117,6 @@
if (__n > __front_spare())
__add_front_capacity(__n - __front_spare());
// __n <= __front_spare()
- size_type __old_n = __n;
iterator __old_begin = __base::begin();
iterator __i = __old_begin;
_BiIter __m = __f;
@@ -2171,7 +2147,6 @@
if (__n > __back_capacity)
__add_back_capacity(__n - __back_capacity);
// __n <= __back_capacity
- size_type __old_n = __n;
iterator __old_end = __base::end();
iterator __i = __old_end;
_BiIter __m = __l;
@@ -2288,19 +2263,14 @@
__split_buffer<pointer, typename __base::__pointer_allocator&>
__buf(max<size_type>(2 * __base::__map_.capacity(), 1),
0, __base::__map_.__alloc());
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try
- {
-#endif // _LIBCPP_NO_EXCEPTIONS
- __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
-#ifndef _LIBCPP_NO_EXCEPTIONS
- }
- catch (...)
- {
- __alloc_traits::deallocate(__a, __buf.front(), __base::__block_size);
- throw;
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
+
+ typedef __allocator_destructor<_Allocator> _Dp;
+ unique_ptr<pointer, _Dp> __hold(
+ __alloc_traits::allocate(__a, __base::__block_size),
+ _Dp(__a, __base::__block_size));
+ __buf.push_back(__hold.get());
+ __hold.release();
+
for (typename __base::__map_pointer __i = __base::__map_.begin();
__i != __base::__map_.end(); ++__i)
__buf.push_back(*__i);
@@ -2436,19 +2406,14 @@
__buf(max<size_type>(2* __base::__map_.capacity(), 1),
__base::__map_.size(),
__base::__map_.__alloc());
-#ifndef _LIBCPP_NO_EXCEPTIONS
- try
- {
-#endif // _LIBCPP_NO_EXCEPTIONS
- __buf.push_back(__alloc_traits::allocate(__a, __base::__block_size));
-#ifndef _LIBCPP_NO_EXCEPTIONS
- }
- catch (...)
- {
- __alloc_traits::deallocate(__a, __buf.back(), __base::__block_size);
- throw;
- }
-#endif // _LIBCPP_NO_EXCEPTIONS
+
+ typedef __allocator_destructor<_Allocator> _Dp;
+ unique_ptr<pointer, _Dp> __hold(
+ __alloc_traits::allocate(__a, __base::__block_size),
+ _Dp(__a, __base::__block_size));
+ __buf.push_back(__hold.get());
+ __hold.release();
+
for (typename __base::__map_pointer __i = __base::__map_.end();
__i != __base::__map_.begin();)
__buf.push_front(*--__i);
@@ -2716,12 +2681,11 @@
typename deque<_Tp, _Allocator>::iterator
deque<_Tp, _Allocator>::erase(const_iterator __f)
{
- difference_type __n = 1;
iterator __b = __base::begin();
difference_type __pos = __f - __b;
iterator __p = __b + __pos;
allocator_type& __a = __base::__alloc();
- if (__pos < (__base::size() - 1) / 2)
+ if (__pos <= (__base::size() - 1) / 2)
{ // erase from front
_VSTD::move_backward(__b, __p, _VSTD::next(__p));
__alloc_traits::destroy(__a, _VSTD::addressof(*__b));
@@ -2759,7 +2723,7 @@
if (__n > 0)
{
allocator_type& __a = __base::__alloc();
- if (__pos < (__base::size() - __n) / 2)
+ if (__pos <= (__base::size() - __n) / 2)
{ // erase from front
iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
for (; __b != __i; ++__b)
@@ -2815,8 +2779,12 @@
inline _LIBCPP_INLINE_VISIBILITY
void
deque<_Tp, _Allocator>::swap(deque& __c)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
__base::swap(__c);
}
diff --git a/include/exception b/include/exception
index cad802e..5a905e7 100644
--- a/include/exception
+++ b/include/exception
@@ -48,7 +48,8 @@
terminate_handler get_terminate() noexcept;
[[noreturn]] void terminate() noexcept;
-bool uncaught_exception() noexcept;
+bool uncaught_exception() noexcept;
+int uncaught_exceptions() noexcept; // C++17
typedef unspecified exception_ptr;
@@ -115,6 +116,7 @@
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
+_LIBCPP_FUNC_VIS int uncaught_exceptions() _NOEXCEPT;
class _LIBCPP_TYPE_VIS exception_ptr;
@@ -193,6 +195,7 @@
throw_with_nested(_Tp&& __t, typename enable_if<
is_class<typename remove_reference<_Tp>::type>::value &&
!is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
+ && !__libcpp_is_final<typename remove_reference<_Tp>::type>::value
>::type* = 0)
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested (_Tp& __t, typename enable_if<
@@ -212,6 +215,7 @@
throw_with_nested(_Tp&& __t, typename enable_if<
!is_class<typename remove_reference<_Tp>::type>::value ||
is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
+ || __libcpp_is_final<typename remove_reference<_Tp>::type>::value
>::type* = 0)
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested (_Tp& __t, typename enable_if<
diff --git a/include/experimental/algorithm b/include/experimental/algorithm
new file mode 100644
index 0000000..ffaa793
--- /dev/null
+++ b/include/experimental/algorithm
@@ -0,0 +1,120 @@
+// -*- C++ -*-
+//===-------------------------- algorithm ---------------------------------===//
+//
+// 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_EXPERIMENTAL_ALGORITHM
+#define _LIBCPP_EXPERIMENTAL_ALGORITHM
+
+/*
+ experimental/algorithm synopsis
+
+#include <algorithm>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+template <class ForwardIterator, class Searcher>
+ForwardIterator search(ForwardIterator first, ForwardIterator last,
+ const Searcher &searcher);
+template <class PopulationIterator, class SampleIterator, class Distance,
+ class UniformRandomNumberGenerator>
+SampleIterator sample(PopulationIterator first, PopulationIterator last,
+ SampleIterator out, Distance n,
+ UniformRandomNumberGenerator &&g);
+
+} // namespace fundamentals_v1
+} // namespace experimental
+} // namespace std
+
+*/
+
+#include <experimental/__config>
+#include <algorithm>
+#include <type_traits>
+
+#include <__undef_min_max>
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+
+template <class _ForwardIterator, class _Searcher>
+_LIBCPP_INLINE_VISIBILITY
+_ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s)
+{ return __s(__f, __l); }
+
+
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+ class _UniformRandomNumberGenerator>
+_LIBCPP_INLINE_VISIBILITY
+_SampleIterator __sample(_PopulationIterator __first,
+ _PopulationIterator __last, _SampleIterator __out,
+ _Distance __n,
+ _UniformRandomNumberGenerator &&__g,
+ input_iterator_tag) {
+
+ _Distance __k = 0;
+ for (; __first != __last && __k < __n; ++__first, (void)++__k)
+ __out[__k] = *__first;
+ _Distance __sz = __k;
+ for (; __first != __last; ++__first, (void)++__k) {
+ _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g);
+ if (__r < __sz)
+ __out[__r] = *__first;
+ }
+ return __out + _VSTD::min(__n, __k);
+}
+
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+ class _UniformRandomNumberGenerator>
+_LIBCPP_INLINE_VISIBILITY
+_SampleIterator __sample(_PopulationIterator __first,
+ _PopulationIterator __last, _SampleIterator __out,
+ _Distance __n,
+ _UniformRandomNumberGenerator &&__g,
+ forward_iterator_tag) {
+ _Distance __unsampled_sz = _VSTD::distance(__first, __last);
+ for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) {
+ _Distance __r =
+ _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
+ if (__r < __n) {
+ *__out++ = *__first;
+ --__n;
+ }
+ }
+ return __out;
+}
+
+template <class _PopulationIterator, class _SampleIterator, class _Distance,
+ class _UniformRandomNumberGenerator>
+_LIBCPP_INLINE_VISIBILITY
+_SampleIterator sample(_PopulationIterator __first,
+ _PopulationIterator __last, _SampleIterator __out,
+ _Distance __n, _UniformRandomNumberGenerator &&__g) {
+ typedef typename iterator_traits<_PopulationIterator>::iterator_category
+ _PopCategory;
+ typedef typename iterator_traits<_PopulationIterator>::difference_type
+ _Difference;
+ typedef typename common_type<_Distance, _Difference>::type _CommonType;
+ _LIBCPP_ASSERT(__n >= 0, "N must be a positive number.");
+ return _VSTD_LFTS::__sample(
+ __first, __last, __out, _CommonType(__n),
+ _VSTD::forward<_UniformRandomNumberGenerator>(__g),
+ _PopCategory());
+}
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */
diff --git a/include/experimental/any b/include/experimental/any
new file mode 100644
index 0000000..a38397a
--- /dev/null
+++ b/include/experimental/any
@@ -0,0 +1,592 @@
+// -*- C++ -*-
+//===------------------------------ any -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_EXPERIMENTAL_ANY
+#define _LIBCPP_EXPERIMENTAL_ANY
+
+/*
+ experimental/any synopsis
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+ class bad_any_cast : public bad_cast
+ {
+ public:
+ virtual const char* what() const noexcept;
+ };
+
+ class any
+ {
+ public:
+
+ // 6.3.1 any construct/destruct
+ any() noexcept;
+
+ any(const any& other);
+ any(any&& other) noexcept;
+
+ template <class ValueType>
+ any(ValueType&& value);
+
+ ~any();
+
+ // 6.3.2 any assignments
+ any& operator=(const any& rhs);
+ any& operator=(any&& rhs) noexcept;
+
+ template <class ValueType>
+ any& operator=(ValueType&& rhs);
+
+ // 6.3.3 any modifiers
+ void clear() noexcept;
+ void swap(any& rhs) noexcept;
+
+ // 6.3.4 any observers
+ bool empty() const noexcept;
+ const type_info& type() const noexcept;
+ };
+
+ // 6.4 Non-member functions
+ void swap(any& x, any& y) noexcept;
+
+ template<class ValueType>
+ ValueType any_cast(const any& operand);
+ template<class ValueType>
+ ValueType any_cast(any& operand);
+ template<class ValueType>
+ ValueType any_cast(any&& operand);
+
+ template<class ValueType>
+ const ValueType* any_cast(const any* operand) noexcept;
+ template<class ValueType>
+ ValueType* any_cast(any* operand) noexcept;
+
+} // namespace fundamentals_v1
+} // namespace experimental
+} // namespace std
+
+*/
+
+#include <experimental/__config>
+#include <memory>
+#include <new>
+#include <typeinfo>
+#include <type_traits>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast
+{
+public:
+ //TODO(EricWF) Enable or delete these.
+ //bad_any_cast() _NOEXCEPT;
+ //virtual ~bad_any_cast() _NOEXCEPT;
+ virtual const char* what() const _NOEXCEPT;
+};
+
+#if _LIBCPP_STD_VER > 11 // C++ > 11
+
+_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY
+inline void __throw_bad_any_cast()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw bad_any_cast();
+#else
+ _VSTD::abort();
+#endif
+}
+
+// Forward declarations
+class any;
+
+template <class _ValueType>
+typename add_pointer<typename add_const<_ValueType>::type>::type
+any_cast(any const *) _NOEXCEPT;
+
+template <class _ValueType>
+typename add_pointer<_ValueType>::type
+any_cast(any *) _NOEXCEPT;
+
+namespace __any_imp
+{
+ typedef typename aligned_storage<3*sizeof(void*), alignment_of<void*>::value>::type
+ _Buffer;
+
+ template <class _Tp>
+ struct _IsSmallObject
+ : public integral_constant<bool
+ , sizeof(_Tp) <= sizeof(_Buffer)
+ && alignment_of<_Buffer>::value
+ % alignment_of<_Tp>::value == 0
+ && is_nothrow_move_constructible<_Tp>::value
+ >
+ {};
+
+ enum class _Action
+ {
+ _Destroy,
+ _Copy,
+ _Move,
+ _Get,
+ _TypeInfo
+ };
+
+ template <class _Tp>
+ struct _SmallHandler;
+
+ template <class _Tp>
+ struct _LargeHandler;
+
+ template <class _Tp>
+ using _Handler = typename conditional<_IsSmallObject<_Tp>::value
+ , _SmallHandler<_Tp>
+ , _LargeHandler<_Tp>
+ >::type;
+ template <class _ValueType>
+ using _EnableIfNotAny = typename
+ enable_if<
+ !is_same<typename decay<_ValueType>::type, any>::value
+ >::type;
+
+} // namespace __any_imp
+
+class any
+{
+public:
+ // 6.3.1 any construct/destruct
+ _LIBCPP_INLINE_VISIBILITY
+ any() _NOEXCEPT : __h(nullptr) {}
+
+ _LIBCPP_INLINE_VISIBILITY
+ any(any const & __other) : __h(nullptr)
+ {
+ if (__other.__h) __other.__call(_Action::_Copy, this);
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ any(any && __other) _NOEXCEPT : __h(nullptr)
+ {
+ if (__other.__h) __other.__call(_Action::_Move, this);
+ }
+
+ template <
+ class _ValueType
+ , class = __any_imp::_EnableIfNotAny<_ValueType>
+ >
+ any(_ValueType && __value);
+
+ _LIBCPP_INLINE_VISIBILITY
+ ~any()
+ {
+ this->clear();
+ }
+
+ // 6.3.2 any assignments
+ _LIBCPP_INLINE_VISIBILITY
+ any & operator=(any const & __rhs)
+ {
+ any(__rhs).swap(*this);
+ return *this;
+ }
+
+ _LIBCPP_INLINE_VISIBILITY
+ any & operator=(any && __rhs) _NOEXCEPT
+ {
+ any(_VSTD::move(__rhs)).swap(*this);
+ return *this;
+ }
+
+ template <
+ class _ValueType
+ , class = __any_imp::_EnableIfNotAny<_ValueType>
+ >
+ any & operator=(_ValueType && __rhs);
+
+ // 6.3.3 any modifiers
+ _LIBCPP_INLINE_VISIBILITY
+ void clear() _NOEXCEPT
+ {
+ if (__h) this->__call(_Action::_Destroy);
+ }
+
+ void swap(any & __rhs) _NOEXCEPT;
+
+ // 6.3.4 any observers
+ _LIBCPP_INLINE_VISIBILITY
+ bool empty() const _NOEXCEPT
+ {
+ return __h == nullptr;
+ }
+
+#if !defined(_LIBCPP_NO_RTTI)
+ _LIBCPP_INLINE_VISIBILITY
+ const type_info & type() const _NOEXCEPT
+ {
+ if (__h) {
+ return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo));
+ } else {
+ return typeid(void);
+ }
+ }
+#endif
+
+private:
+ typedef __any_imp::_Action _Action;
+
+ typedef void* (*_HandleFuncPtr)(_Action, any const *, any *, const type_info *);
+
+ union _Storage
+ {
+ void * __ptr;
+ __any_imp::_Buffer __buf;
+ };
+
+ _LIBCPP_ALWAYS_INLINE
+ void * __call(_Action __a, any * __other = nullptr,
+ type_info const * __info = nullptr) const
+ {
+ return __h(__a, this, __other, __info);
+ }
+
+ _LIBCPP_ALWAYS_INLINE
+ void * __call(_Action __a, any * __other = nullptr,
+ type_info const * __info = nullptr)
+ {
+ return __h(__a, this, __other, __info);
+ }
+
+ template <class>
+ friend struct __any_imp::_SmallHandler;
+ template <class>
+ friend struct __any_imp::_LargeHandler;
+
+ template <class _ValueType>
+ friend typename add_pointer<typename add_const<_ValueType>::type>::type
+ any_cast(any const *) _NOEXCEPT;
+
+ template <class _ValueType>
+ friend typename add_pointer<_ValueType>::type
+ any_cast(any *) _NOEXCEPT;
+
+ _HandleFuncPtr __h;
+ _Storage __s;
+};
+
+namespace __any_imp
+{
+
+ template <class _Tp>
+ struct _LIBCPP_TYPE_VIS_ONLY _SmallHandler
+ {
+ _LIBCPP_INLINE_VISIBILITY
+ static void* __handle(_Action __act, any const * __this, any * __other,
+ type_info const * __info)
+ {
+ switch (__act)
+ {
+ case _Action::_Destroy:
+ __destroy(const_cast<any &>(*__this));
+ return nullptr;
+ case _Action::_Copy:
+ __copy(*__this, *__other);
+ return nullptr;
+ case _Action::_Move:
+ __move(const_cast<any &>(*__this), *__other);
+ return nullptr;
+ case _Action::_Get:
+ return __get(const_cast<any &>(*__this), __info);
+ case _Action::_TypeInfo:
+ return __type_info();
+ }
+ }
+
+ template <class _Up>
+ _LIBCPP_INLINE_VISIBILITY
+ static void __create(any & __dest, _Up && __v)
+ {
+ ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Up>(__v));
+ __dest.__h = &_SmallHandler::__handle;
+ }
+
+ private:
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void __destroy(any & __this)
+ {
+ _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
+ __value.~_Tp();
+ __this.__h = nullptr;
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void __copy(any const & __this, any & __dest)
+ {
+ _SmallHandler::__create(__dest, *static_cast<_Tp const *>(
+ static_cast<void const *>(&__this.__s.__buf)));
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void __move(any & __this, any & __dest)
+ {
+ _SmallHandler::__create(__dest, _VSTD::move(
+ *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf))));
+ __destroy(__this);
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void* __get(any & __this, type_info const * __info)
+ {
+#if !defined(_LIBCPP_NO_RTTI)
+ if (typeid(_Tp) == *__info) {
+ return static_cast<void*>(&__this.__s.__buf);
+ }
+ return nullptr;
+#else
+ return static_cast<void*>(&__this.__s.__buf);
+#endif
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void* __type_info()
+ {
+#if !defined(_LIBCPP_NO_RTTI)
+ return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
+#else
+ return nullptr;
+#endif
+ }
+ };
+
+ template <class _Tp>
+ struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler
+ {
+ _LIBCPP_INLINE_VISIBILITY
+ static void* __handle(_Action __act, any const * __this, any * __other,
+ type_info const * __info)
+ {
+ switch (__act)
+ {
+ case _Action::_Destroy:
+ __destroy(const_cast<any &>(*__this));
+ return nullptr;
+ case _Action::_Copy:
+ __copy(*__this, *__other);
+ return nullptr;
+ case _Action::_Move:
+ __move(const_cast<any &>(*__this), *__other);
+ return nullptr;
+ case _Action::_Get:
+ return __get(const_cast<any &>(*__this), __info);
+ case _Action::_TypeInfo:
+ return __type_info();
+ }
+ }
+
+ template <class _Up>
+ _LIBCPP_INLINE_VISIBILITY
+ static void __create(any & __dest, _Up && __v)
+ {
+ typedef allocator<_Tp> _Alloc;
+ typedef __allocator_destructor<_Alloc> _Dp;
+ _Alloc __a;
+ unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
+ ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Up>(__v));
+ __dest.__s.__ptr = __hold.release();
+ __dest.__h = &_LargeHandler::__handle;
+ }
+
+ private:
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void __destroy(any & __this)
+ {
+ delete static_cast<_Tp*>(__this.__s.__ptr);
+ __this.__h = nullptr;
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void __copy(any const & __this, any & __dest)
+ {
+ _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr));
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void __move(any & __this, any & __dest)
+ {
+ __dest.__s.__ptr = __this.__s.__ptr;
+ __dest.__h = &_LargeHandler::__handle;
+ __this.__h = nullptr;
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void* __get(any & __this, type_info const * __info)
+ {
+#if !defined(_LIBCPP_NO_RTTI)
+ if (typeid(_Tp) == *__info) {
+ return static_cast<void*>(__this.__s.__ptr);
+ }
+ return nullptr;
+#else
+ return static_cast<void*>(__this.__s.__ptr);
+#endif
+ }
+
+ _LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY
+ static void* __type_info()
+ {
+#if !defined(_LIBCPP_NO_RTTI)
+ return const_cast<void*>(static_cast<void const *>(&typeid(_Tp)));
+#else
+ return nullptr;
+#endif
+ }
+ };
+
+} // namespace __any_imp
+
+
+template <class _ValueType, class>
+_LIBCPP_INLINE_VISIBILITY
+any::any(_ValueType && __v) : __h(nullptr)
+{
+ typedef typename decay<_ValueType>::type _Tp;
+ static_assert(is_copy_constructible<_Tp>::value,
+ "_ValueType must be CopyConstructible.");
+ typedef __any_imp::_Handler<_Tp> _HandlerType;
+ _HandlerType::__create(*this, _VSTD::forward<_ValueType>(__v));
+}
+
+template <class _ValueType, class>
+_LIBCPP_INLINE_VISIBILITY
+any & any::operator=(_ValueType && __v)
+{
+ typedef typename decay<_ValueType>::type _Tp;
+ static_assert(is_copy_constructible<_Tp>::value,
+ "_ValueType must be CopyConstructible.");
+ any(_VSTD::forward<_ValueType>(__v)).swap(*this);
+ return *this;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void any::swap(any & __rhs) _NOEXCEPT
+{
+ if (__h && __rhs.__h) {
+ any __tmp;
+ __rhs.__call(_Action::_Move, &__tmp);
+ this->__call(_Action::_Move, &__rhs);
+ __tmp.__call(_Action::_Move, this);
+ }
+ else if (__h) {
+ this->__call(_Action::_Move, &__rhs);
+ }
+ else if (__rhs.__h) {
+ __rhs.__call(_Action::_Move, this);
+ }
+}
+
+// 6.4 Non-member functions
+
+inline _LIBCPP_INLINE_VISIBILITY
+void swap(any & __lhs, any & __rhs) _NOEXCEPT
+{
+ __lhs.swap(__rhs);
+}
+
+template <class _ValueType>
+_LIBCPP_INLINE_VISIBILITY
+_ValueType any_cast(any const & __v)
+{
+ static_assert(
+ is_reference<_ValueType>::value
+ || is_copy_constructible<_ValueType>::value,
+ "_ValueType is required to be a reference or a CopyConstructible type.");
+ typedef typename add_const<typename remove_reference<_ValueType>::type>::type
+ _Tp;
+ _Tp * __tmp = any_cast<_Tp>(&__v);
+ if (__tmp == nullptr)
+ __throw_bad_any_cast();
+ return *__tmp;
+}
+
+template <class _ValueType>
+_LIBCPP_INLINE_VISIBILITY
+_ValueType any_cast(any & __v)
+{
+ static_assert(
+ is_reference<_ValueType>::value
+ || is_copy_constructible<_ValueType>::value,
+ "_ValueType is required to be a reference or a CopyConstructible type.");
+ typedef typename remove_reference<_ValueType>::type _Tp;
+ _Tp * __tmp = any_cast<_Tp>(&__v);
+ if (__tmp == nullptr)
+ __throw_bad_any_cast();
+ return *__tmp;
+}
+
+template <class _ValueType>
+_LIBCPP_INLINE_VISIBILITY
+_ValueType any_cast(any && __v)
+{
+ static_assert(
+ is_reference<_ValueType>::value
+ || is_copy_constructible<_ValueType>::value,
+ "_ValueType is required to be a reference or a CopyConstructible type.");
+ typedef typename remove_reference<_ValueType>::type _Tp;
+ _Tp * __tmp = any_cast<_Tp>(&__v);
+ if (__tmp == nullptr)
+ __throw_bad_any_cast();
+ return *__tmp;
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+typename add_pointer<typename add_const<_ValueType>::type>::type
+any_cast(any const * __any) _NOEXCEPT
+{
+ static_assert(!is_reference<_ValueType>::value,
+ "_ValueType may not be a reference.");
+ return any_cast<_ValueType>(const_cast<any *>(__any));
+}
+
+template <class _ValueType>
+_LIBCPP_INLINE_VISIBILITY
+typename add_pointer<_ValueType>::type
+any_cast(any * __any) _NOEXCEPT
+{
+ using __any_imp::_Action;
+ static_assert(!is_reference<_ValueType>::value,
+ "_ValueType may not be a reference.");
+ typedef typename add_pointer<_ValueType>::type _ReturnType;
+ if (__any && __any->__h) {
+
+ return static_cast<_ReturnType>(
+ __any->__call(_Action::_Get, nullptr,
+#if !defined(_LIBCPP_NO_RTTI)
+ &typeid(_ValueType)
+#else
+ nullptr
+#endif
+ ));
+
+ }
+ return nullptr;
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif // _LIBCPP_EXPERIMENTAL_ANY
diff --git a/include/experimental/chrono b/include/experimental/chrono
index 738ded8..ca9e5f8 100644
--- a/include/experimental/chrono
+++ b/include/experimental/chrono
@@ -45,12 +45,12 @@
_LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS
-#if __has_feature(cxx_variable_templates)
+#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
template <class _Rep> _LIBCPP_CONSTEXPR bool treat_as_floating_point_v
= treat_as_floating_point<_Rep>::value;
-#endif /* __has_feature(cxx_variable_templates) */
+#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */
_LIBCPP_END_NAMESPACE_CHRONO_LFTS
diff --git a/include/experimental/functional b/include/experimental/functional
new file mode 100644
index 0000000..f5a905f
--- /dev/null
+++ b/include/experimental/functional
@@ -0,0 +1,133 @@
+// -*- C++ -*-
+//===-------------------------- functional --------------------------------===//
+//
+// 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_EXPERIMENTAL_FUNCTIONAL
+#define _LIBCPP_EXPERIMENTAL_FUNCTIONAL
+
+/*
+ experimental/functional synopsis
+
+#include <algorithm>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+ // See C++14 §20.9.9, Function object binders
+ template <class T> constexpr bool is_bind_expression_v
+ = is_bind_expression<T>::value;
+ template <class T> constexpr int is_placeholder_v
+ = is_placeholder<T>::value;
+
+ // 4.2, Class template function
+ template<class> class function; // undefined
+ template<class R, class... ArgTypes> class function<R(ArgTypes...)>;
+
+ template<class R, class... ArgTypes>
+ void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
+
+ template<class R, class... ArgTypes>
+ bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
+ template<class R, class... ArgTypes>
+ bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
+ template<class R, class... ArgTypes>
+ bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
+ template<class R, class... ArgTypes>
+ bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept;
+
+ // 4.3, Searchers
+ template<class ForwardIterator, class BinaryPredicate = equal_to<>>
+ class default_searcher;
+
+ template<class RandomAccessIterator,
+ class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
+ class BinaryPredicate = equal_to<>>
+ class boyer_moore_searcher;
+
+ template<class RandomAccessIterator,
+ class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
+ class BinaryPredicate = equal_to<>>
+ class boyer_moore_horspool_searcher;
+
+ template<class ForwardIterator, class BinaryPredicate = equal_to<>>
+ default_searcher<ForwardIterator, BinaryPredicate>
+ make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
+ BinaryPredicate pred = BinaryPredicate());
+
+ template<class RandomAccessIterator,
+ class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
+ class BinaryPredicate = equal_to<>>
+ boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
+ make_boyer_moore_searcher(
+ RandomAccessIterator pat_first, RandomAccessIterator pat_last,
+ Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+
+ template<class RandomAccessIterator,
+ class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
+ class BinaryPredicate = equal_to<>>
+ boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
+ make_boyer_moore_horspool_searcher(
+ RandomAccessIterator pat_first, RandomAccessIterator pat_last,
+ Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate());
+
+ } // namespace fundamentals_v1
+ } // namespace experimental
+
+ template<class R, class... ArgTypes, class Alloc>
+ struct uses_allocator<experimental::function<R(ArgTypes...)>, Alloc>;
+
+} // namespace std
+
+*/
+
+#include <experimental/__config>
+#include <functional>
+#include <algorithm>
+
+#include <__undef_min_max>
+
+#include <__debug>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+// default searcher
+template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+class default_searcher {
+public:
+ default_searcher(_ForwardIterator __f, _ForwardIterator __l,
+ _BinaryPredicate __p = _BinaryPredicate())
+ : __first_(__f), __last_(__l), __pred_(__p) {}
+
+ template <typename _ForwardIterator2>
+ _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const {
+ return _VSTD::search(__f, __l, __first_, __last_, __pred_);
+ }
+
+private:
+ _ForwardIterator __first_;
+ _ForwardIterator __last_;
+ _BinaryPredicate __pred_;
+ };
+
+template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+default_searcher<_ForwardIterator, _BinaryPredicate>
+make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ())
+{
+ return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p);
+}
+
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */
diff --git a/include/experimental/ratio b/include/experimental/ratio
index a393cef..757f24e 100644
--- a/include/experimental/ratio
+++ b/include/experimental/ratio
@@ -48,7 +48,7 @@
_LIBCPP_BEGIN_NAMESPACE_LFTS
-#if __has_feature(cxx_variable_templates)
+#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_equal_v
= ratio_equal<_R1, _R2>::value;
@@ -68,10 +68,10 @@
template <class _R1, class _R2> _LIBCPP_CONSTEXPR bool ratio_greater_equal_v
= ratio_greater_equal<_R1, _R2>::value;
-#endif /* __has_feature(cxx_variable_templates) */
+#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */
_LIBCPP_END_NAMESPACE_LFTS
#endif /* _LIBCPP_STD_VER > 11 */
-#endif _LIBCPP_EXPERIMENTAL_RATIO
\ No newline at end of file
+#endif // _LIBCPP_EXPERIMENTAL_RATIO
diff --git a/include/experimental/system_error b/include/experimental/system_error
index 9b9ab33..2ec2385 100644
--- a/include/experimental/system_error
+++ b/include/experimental/system_error
@@ -46,7 +46,7 @@
_LIBCPP_BEGIN_NAMESPACE_LFTS
-#if __has_feature(cxx_variable_templates)
+#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
template <class _Tp> _LIBCPP_CONSTEXPR bool is_error_code_enum_v
= is_error_code_enum<_Tp>::value;
@@ -54,7 +54,7 @@
template <class _Tp> _LIBCPP_CONSTEXPR bool is_error_condition_enum_v
= is_error_condition_enum<_Tp>::value;
-#endif /* __has_feature(cxx_variable_templates) */
+#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */
_LIBCPP_END_NAMESPACE_LFTS
diff --git a/include/experimental/tuple b/include/experimental/tuple
new file mode 100644
index 0000000..50d1e05
--- /dev/null
+++ b/include/experimental/tuple
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+//===----------------------------- tuple ----------------------------------===//
+//
+// 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_EXPERIMENTAL_TUPLE
+#define _LIBCPP_EXPERIMENTAL_TUPLE
+
+/*
+ experimental/tuple synopsis
+
+// C++1y
+
+#include <tuple>
+
+namespace std {
+namespace experimental {
+inline namespace fundamentals_v1 {
+
+ // See C++14 20.4.2.5, tuple helper classes
+ template <class T> constexpr size_t tuple_size_v
+ = tuple_size<T>::value;
+
+ // 3.2.2, Calling a function with a tuple of arguments
+ template <class F, class Tuple>
+ constexpr decltype(auto) apply(F&& f, Tuple&& t);
+
+} // namespace fundamentals_v1
+} // namespace experimental
+} // namespace std
+
+ */
+
+# include <experimental/__config>
+
+#if _LIBCPP_STD_VER > 11
+
+# include <tuple>
+# include <utility>
+# include <__functional_base>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
+template <class _Tp>
+_LIBCPP_CONSTEXPR size_t tuple_size_v = tuple_size<_Tp>::value;
+#endif
+
+template <class _Fn, class _Tuple, size_t ..._Id>
+inline _LIBCPP_INLINE_VISIBILITY
+decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
+ integer_sequence<size_t, _Id...>) {
+ return _VSTD::__invoke(
+ _VSTD::forward<_Fn>(__f),
+ _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...
+ );
+}
+
+template <class _Fn, class _Tuple>
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
+decltype(auto) apply(_Fn && __f, _Tuple && __t) {
+ return _VSTD_LFTS::__apply_tuple_impl(
+ _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
+ make_index_sequence<tuple_size<typename decay<_Tuple>::type>::value>()
+ );
+}
+
+_LIBCPP_END_NAMESPACE_LFTS
+
+#endif /* _LIBCPP_STD_VER > 11 */
+
+#endif /* _LIBCPP_EXPERIMENTAL_TUPLE */
diff --git a/include/experimental/type_traits b/include/experimental/type_traits
index 35cdada..ae49fc1 100644
--- a/include/experimental/type_traits
+++ b/include/experimental/type_traits
@@ -190,7 +190,7 @@
_LIBCPP_BEGIN_NAMESPACE_LFTS
-#if __has_feature(cxx_variable_templates)
+#ifndef _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
// C++14 20.10.4.1, primary type categories
@@ -397,7 +397,7 @@
template <class _Tp, class _Up> _LIBCPP_CONSTEXPR bool is_convertible_v
= is_convertible<_Tp, _Up>::value;
-#endif /* __has_feature(cxx_variable_templates) */
+#endif /* _LIBCPP_HAS_NO_VARIABLE_TEMPLATES */
// 3.3.2, Other type transformations
/*
diff --git a/include/ext/hash_map b/include/ext/hash_map
index 36cd595..31fcedf 100644
--- a/include/ext/hash_map
+++ b/include/ext/hash_map
@@ -203,6 +203,7 @@
#include <__hash_table>
#include <functional>
#include <stdexcept>
+#include <type_traits>
#include <ext/__hash>
#if __DEPRECATED
@@ -213,16 +214,16 @@
#endif
#endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
+#endif
namespace __gnu_cxx {
using namespace std;
-template <class _Tp, class _Hash, bool = is_empty<_Hash>::value
-#if __has_feature(is_final)
- && !__is_final(_Hash)
-#endif
+template <class _Tp, class _Hash,
+ bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
>
class __hash_map_hasher
: private _Hash
@@ -255,10 +256,8 @@
{return __hash_(__x);}
};
-template <class _Tp, class _Pred, bool = is_empty<_Pred>::value
-#if __has_feature(is_final)
- && !__is_final(_Pred)
-#endif
+template <class _Tp, class _Pred,
+ bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
>
class __hash_map_equal
: private _Pred
@@ -493,13 +492,7 @@
typedef pair<key_type, mapped_type> __value_type;
typedef __hash_map_hasher<__value_type, hasher> __hasher;
typedef __hash_map_equal<__value_type, key_equal> __key_equal;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__value_type>
-#else
- rebind_alloc<__value_type>::other
-#endif
- __allocator_type;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __value_type>::type __allocator_type;
typedef __hash_table<__value_type, __hasher,
__key_equal, __allocator_type> __table;
@@ -772,13 +765,7 @@
typedef pair<key_type, mapped_type> __value_type;
typedef __hash_map_hasher<__value_type, hasher> __hasher;
typedef __hash_map_equal<__value_type, key_equal> __key_equal;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__value_type>
-#else
- rebind_alloc<__value_type>::other
-#endif
- __allocator_type;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __value_type>::type __allocator_type;
typedef __hash_table<__value_type, __hasher,
__key_equal, __allocator_type> __table;
diff --git a/include/forward_list b/include/forward_list
index a442a9b..8a87fc5 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -107,8 +107,7 @@
iterator erase_after(const_iterator first, const_iterator last);
void swap(forward_list& x)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
void resize(size_type n);
void resize(size_type n, const value_type& v);
@@ -365,24 +364,12 @@
typedef typename allocator_traits<allocator_type>::void_pointer void_pointer;
typedef __forward_list_node<value_type, void_pointer> __node;
typedef typename __begin_node_of<value_type, void_pointer>::type __begin_node;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__node>
-#else
- rebind_alloc<__node>::other
-#endif
- __node_allocator;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
typedef allocator_traits<__node_allocator> __node_traits;
typedef typename __node_traits::pointer __node_pointer;
typedef typename __node_traits::pointer __node_const_pointer;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__begin_node>
-#else
- rebind_alloc<__begin_node>::other
-#endif
- __begin_node_allocator;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __begin_node>::type __begin_node_allocator;
typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
__compressed_pair<__begin_node, __node_allocator> __before_begin_;
@@ -443,8 +430,12 @@
public:
void swap(__forward_list_base& __x)
- _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
+ __is_nothrow_swappable<__node_allocator>::value);
+#endif
protected:
void clear() _NOEXCEPT;
@@ -466,26 +457,6 @@
void __move_assign_alloc(__forward_list_base& __x, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value)
{__alloc() = _VSTD::move(__x.__alloc());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
- _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __node_traits::propagate_on_container_swap::value>());}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
- false_type)
- _NOEXCEPT
- {}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y,
- true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
};
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -524,10 +495,15 @@
inline _LIBCPP_INLINE_VISIBILITY
void
__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
- _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
+ __is_nothrow_swappable<__node_allocator>::value)
+#endif
{
- __swap_alloc(__alloc(), __x.__alloc());
+ __swap_allocator(__alloc(), __x.__alloc(),
+ integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
using _VSTD::swap;
swap(__before_begin()->__next_, __x.__before_begin()->__next_);
}
@@ -715,8 +691,12 @@
_LIBCPP_INLINE_VISIBILITY
void swap(forward_list& __x)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
_NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<__node_allocator>::value)
+#endif
{base::swap(__x);}
void resize(size_type __n);
diff --git a/include/fstream b/include/fstream
index ace5eb9..1f289ed 100644
--- a/include/fstream
+++ b/include/fstream
@@ -206,8 +206,10 @@
// 27.9.1.4 Members:
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
basic_filebuf* open(const char* __s, ios_base::openmode __mode);
basic_filebuf* open(const string& __s, ios_base::openmode __mode);
+#endif
basic_filebuf* close();
protected:
@@ -463,6 +465,7 @@
return __file_ != 0;
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
@@ -550,6 +553,7 @@
{
return open(__s.c_str(), __mode);
}
+#endif
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
@@ -1005,8 +1009,10 @@
typedef typename traits_type::off_type off_type;
basic_ifstream();
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
basic_ifstream(basic_ifstream&& __rhs);
#endif
@@ -1018,8 +1024,10 @@
basic_filebuf<char_type, traits_type>* rdbuf() const;
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
void open(const char* __s, ios_base::openmode __mode = ios_base::in);
void open(const string& __s, ios_base::openmode __mode = ios_base::in);
+#endif
void close();
private:
@@ -1033,6 +1041,7 @@
{
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
@@ -1050,6 +1059,7 @@
if (__sb_.open(__s, __mode | ios_base::in) == 0)
this->setstate(ios_base::failbit);
}
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1107,6 +1117,7 @@
return __sb_.is_open();
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
void
basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
@@ -1126,6 +1137,7 @@
else
this->setstate(ios_base::failbit);
}
+#endif
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1163,8 +1175,10 @@
basic_filebuf<char_type, traits_type>* rdbuf() const;
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
void open(const char* __s, ios_base::openmode __mode = ios_base::out);
void open(const string& __s, ios_base::openmode __mode = ios_base::out);
+#endif
void close();
private:
@@ -1178,6 +1192,7 @@
{
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
@@ -1195,6 +1210,7 @@
if (__sb_.open(__s, __mode | ios_base::out) == 0)
this->setstate(ios_base::failbit);
}
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1252,6 +1268,7 @@
return __sb_.is_open();
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
void
basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
@@ -1271,6 +1288,7 @@
else
this->setstate(ios_base::failbit);
}
+#endif
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1295,8 +1313,10 @@
typedef typename traits_type::off_type off_type;
basic_fstream();
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
basic_fstream(basic_fstream&& __rhs);
#endif
@@ -1308,8 +1328,10 @@
basic_filebuf<char_type, traits_type>* rdbuf() const;
bool is_open() const;
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
+#endif
void close();
private:
@@ -1323,6 +1345,7 @@
{
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
@@ -1340,6 +1363,7 @@
if (__sb_.open(__s, __mode) == 0)
this->setstate(ios_base::failbit);
}
+#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1397,6 +1421,7 @@
return __sb_.is_open();
}
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
template <class _CharT, class _Traits>
void
basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
@@ -1416,6 +1441,7 @@
else
this->setstate(ios_base::failbit);
}
+#endif
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
diff --git a/include/functional b/include/functional
index 070347a..6c57de0 100644
--- a/include/functional
+++ b/include/functional
@@ -1234,11 +1234,9 @@
mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const)
{return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);}
-#ifdef _LIBCPP_HAS_NO_VARIADICS
-
-#include <__functional_03>
-
-#else // _LIBCPP_HAS_NO_VARIADICS
+////////////////////////////////////////////////////////////////////////////////
+// MEMFUN
+//==============================================================================
template <class _Tp>
class __mem_fn
@@ -1253,14 +1251,34 @@
public:
_LIBCPP_INLINE_VISIBILITY __mem_fn(type __f) : __f_(__f) {}
+#ifndef _LIBCPP_HAS_NO_VARIADICS
// invoke
template <class... _ArgTypes>
- _LIBCPP_INLINE_VISIBILITY
- typename __invoke_return<type, _ArgTypes...>::type
- operator() (_ArgTypes&&... __args) const
- {
- return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
- }
+ _LIBCPP_INLINE_VISIBILITY
+ typename __invoke_return<type, _ArgTypes...>::type
+ operator() (_ArgTypes&&... __args) const {
+ return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
+ }
+#else
+
+ template <class _A0>
+ typename __invoke_return0<type, _A0>::type
+ operator() (_A0& __a0) const {
+ return __invoke(__f_, __a0);
+ }
+
+ template <class _A0, class _A1>
+ typename __invoke_return1<type, _A0, _A1>::type
+ operator() (_A0& __a0, _A1& __a1) const {
+ return __invoke(__f_, __a0, __a1);
+ }
+
+ template <class _A0, class _A1, class _A2>
+ typename __invoke_return2<type, _A0, _A1, _A2>::type
+ operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
+ return __invoke(__f_, __a0, __a1, __a2);
+ }
+#endif
};
template<class _Rp, class _Tp>
@@ -1271,6 +1289,10 @@
return __mem_fn<_Rp _Tp::*>(__pm);
}
+////////////////////////////////////////////////////////////////////////////////
+// FUNCTION
+//==============================================================================
+
// bad_function_call
class _LIBCPP_EXCEPTION_ABI bad_function_call
@@ -1283,7 +1305,7 @@
namespace __function
{
-template<class _Rp, class ..._ArgTypes>
+template<class _Rp>
struct __maybe_derive_from_unary_function
{
};
@@ -1294,7 +1316,7 @@
{
};
-template<class _Rp, class ..._ArgTypes>
+template<class _Rp>
struct __maybe_derive_from_binary_function
{
};
@@ -1305,6 +1327,12 @@
{
};
+} // namespace __function
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+namespace __function {
+
template<class _Fp> class __base;
template<class _Rp, class ..._ArgTypes>
@@ -1367,7 +1395,8 @@
__base<_Rp(_ArgTypes...)>*
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1393,7 +1422,8 @@
void
__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
@@ -1654,13 +1684,7 @@
if (__not_null(__f))
{
typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<_FF>
-#else
- rebind_alloc<_FF>::other
-#endif
- _Ap;
+ typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
_Ap __a(__a0);
if (sizeof(_FF) <= sizeof(__buf_) &&
is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value)
@@ -1852,6 +1876,16 @@
swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT
{return __x.swap(__y);}
+#else // _LIBCPP_HAS_NO_VARIADICS
+
+#include <__functional_03>
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// BIND
+//==============================================================================
+
template<class _Tp> struct __is_bind_expression : public false_type {};
template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression
: public __is_bind_expression<typename remove_cv<_Tp>::type> {};
@@ -1882,6 +1916,9 @@
struct __is_placeholder<placeholders::__ph<_Np> >
: public integral_constant<int, _Np> {};
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
template <class _Tp, class _Uj>
inline _LIBCPP_INLINE_VISIBILITY
_Tp&
@@ -2000,27 +2037,27 @@
};
template <class _Fp, class _BoundArgs, class _TupleUj>
-struct _is_valid_bind_return
+struct __is_valid_bind_return
{
static const bool value = false;
};
template <class _Fp, class ..._BoundArgs, class _TupleUj>
-struct _is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
+struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj>
{
static const bool value = __invokable<_Fp,
typename __mu_return<_BoundArgs, _TupleUj>::type...>::value;
};
template <class _Fp, class ..._BoundArgs, class _TupleUj>
-struct _is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
+struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj>
{
static const bool value = __invokable<_Fp,
typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
};
template <class _Fp, class _BoundArgs, class _TupleUj,
- bool = _is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
+ bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
struct __bind_return;
template <class _Fp, class ..._BoundArgs, class _TupleUj>
@@ -2190,12 +2227,13 @@
typename enable_if
<
is_convertible<typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type,
- result_type>::value,
+ result_type>::value || is_void<_Rp>::value,
result_type
>::type
operator()(_Args&& ...__args)
{
- return base::operator()(_VSTD::forward<_Args>(__args)...);
+ typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+ return _Invoker::__call(static_cast<base&>(*this), _VSTD::forward<_Args>(__args)...);
}
template <class ..._Args>
@@ -2203,12 +2241,13 @@
typename enable_if
<
is_convertible<typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type,
- result_type>::value,
+ result_type>::value || is_void<_Rp>::value,
result_type
>::type
operator()(_Args&& ...__args) const
{
- return base::operator()(_VSTD::forward<_Args>(__args)...);
+ typedef __invoke_void_return_wrapper<_Rp> _Invoker;
+ return _Invoker::__call(static_cast<base const&>(*this), _VSTD::forward<_Args>(__args)...);
}
};
@@ -2404,14 +2443,14 @@
size_t __b;
size_t __c;
size_t __d;
- };
+ } __s;
} __u;
- __u.__a = 0;
- __u.__b = 0;
- __u.__c = 0;
- __u.__d = 0;
+ __u.__s.__a = 0;
+ __u.__s.__b = 0;
+ __u.__s.__c = 0;
+ __u.__s.__d = 0;
__u.__t = __v;
- return __u.__a ^ __u.__b ^ __u.__c ^ __u.__d;
+ return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d;
#elif defined(__x86_64__)
// Zero out padding bits
union
@@ -2421,12 +2460,12 @@
{
size_t __a;
size_t __b;
- };
+ } __s;
} __u;
- __u.__a = 0;
- __u.__b = 0;
+ __u.__s.__a = 0;
+ __u.__s.__b = 0;
__u.__t = __v;
- return __u.__a ^ __u.__b;
+ return __u.__s.__a ^ __u.__s.__b;
#else
return __scalar_hash<long double>::operator()(__v);
#endif
@@ -2449,6 +2488,15 @@
};
#endif
+
+#if _LIBCPP_STD_VER > 14
+template <class _Fn, class ..._Args>
+result_of_t<_Fn&&(_Args&&...)>
+invoke(_Fn&& __f, _Args&&... __args) {
+ return __invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
+}
+#endif
+
// struct hash<T*> in <memory>
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/future b/include/future
index ad7af72..5b5afe6 100644
--- a/include/future
+++ b/include/future
@@ -329,7 +329,7 @@
template <class F>
explicit packaged_task(F&& f);
template <class F, class Allocator>
- explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+ packaged_task(allocator_arg_t, const Allocator& a, F&& f);
~packaged_task();
// no copy
@@ -651,7 +651,6 @@
#endif
::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
this->__state_ |= base::__constructed | base::ready;
- __lk.unlock();
__cv_.notify_all();
}
@@ -672,7 +671,6 @@
::new(&__value_) _Rp(_VSTD::forward<_Arg>(__arg));
this->__state_ |= base::__constructed;
__thread_local_data()->__make_ready_at_thread_exit(this);
- __lk.unlock();
}
template <class _Rp>
@@ -733,7 +731,6 @@
#endif
__value_ = _VSTD::addressof(__arg);
this->__state_ |= base::__constructed | base::ready;
- __lk.unlock();
__cv_.notify_all();
}
@@ -749,7 +746,6 @@
__value_ = _VSTD::addressof(__arg);
this->__state_ |= base::__constructed;
__thread_local_data()->__make_ready_at_thread_exit(this);
- __lk.unlock();
}
template <class _Rp>
@@ -2046,7 +2042,7 @@
>::type
>
_LIBCPP_INLINE_VISIBILITY
- explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
+ packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
: __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
__p_(allocator_arg, __a) {}
// ~packaged_task() = default;
@@ -2177,7 +2173,7 @@
>::type
>
_LIBCPP_INLINE_VISIBILITY
- explicit packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
+ packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
: __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)),
__p_(allocator_arg, __a) {}
// ~packaged_task() = default;
diff --git a/include/iostream b/include/iostream
index ddf2484..136a849 100644
--- a/include/iostream
+++ b/include/iostream
@@ -46,13 +46,17 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#ifndef _LIBCPP_HAS_NO_STDIN
extern _LIBCPP_FUNC_VIS istream cin;
-extern _LIBCPP_FUNC_VIS ostream cout;
-extern _LIBCPP_FUNC_VIS ostream cerr;
-extern _LIBCPP_FUNC_VIS ostream clog;
extern _LIBCPP_FUNC_VIS wistream wcin;
+#endif
+#ifndef _LIBCPP_HAS_NO_STDOUT
+extern _LIBCPP_FUNC_VIS ostream cout;
extern _LIBCPP_FUNC_VIS wostream wcout;
+#endif
+extern _LIBCPP_FUNC_VIS ostream cerr;
extern _LIBCPP_FUNC_VIS wostream wcerr;
+extern _LIBCPP_FUNC_VIS ostream clog;
extern _LIBCPP_FUNC_VIS wostream wclog;
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/iterator b/include/iterator
index 05d7412..c06ef8f 100644
--- a/include/iterator
+++ b/include/iterator
@@ -214,7 +214,7 @@
typedef traits traits_type;
typedef basic_istream<charT,traits> istream_type;
- istream_iterator();
+ constexpr istream_iterator();
istream_iterator(istream_type& s);
istream_iterator(const istream_iterator& x);
~istream_iterator();
@@ -575,7 +575,7 @@
_LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n)
{current += __n; return *this;}
_LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const
- {return current[-__n-1];}
+ {return *(*this + __n);}
};
template <class _Iter1, class _Iter2>
@@ -765,7 +765,7 @@
istream_type* __in_stream_;
_Tp __value_;
public:
- _LIBCPP_INLINE_VISIBILITY istream_iterator() : __in_stream_(0) {}
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {}
_LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s)
{
if (!(*__in_stream_ >> __value_))
@@ -1112,8 +1112,6 @@
>::type
__unwrap_iter(__wrap_iter<_Tp*>);
-template <class _Tp, class _Alloc> class _LIBCPP_TYPE_VIS_ONLY vector;
-
template <class _Iter>
class __wrap_iter
{
@@ -1243,7 +1241,7 @@
template <class _Up> friend class __wrap_iter;
template <class _CharT, class _Traits, class _Alloc> friend class basic_string;
- template <class _Tp, class _Alloc> friend class vector;
+ template <class _Tp, class _Alloc> friend class _LIBCPP_TYPE_VIS_ONLY vector;
template <class _Iter1, class _Iter2>
friend
diff --git a/include/list b/include/list
index 13e1199..14201a8 100644
--- a/include/list
+++ b/include/list
@@ -118,8 +118,7 @@
void resize(size_type sz, const value_type& c);
void swap(list&)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value); // C++17
void clear() noexcept;
void splice(const_iterator position, list& x);
@@ -515,13 +514,7 @@
typedef __list_const_iterator<value_type, __void_pointer> const_iterator;
typedef __list_node_base<value_type, __void_pointer> __node_base;
typedef __list_node<value_type, __void_pointer> __node;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__node>
-#else
- rebind_alloc<__node>::other
-#endif
- __node_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
typedef allocator_traits<__node_allocator> __node_alloc_traits;
typedef typename __node_alloc_traits::pointer __node_pointer;
typedef typename __node_alloc_traits::pointer __node_const_pointer;
@@ -529,13 +522,7 @@
typedef typename __alloc_traits::const_pointer const_pointer;
typedef typename __alloc_traits::difference_type difference_type;
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__node_base>
-#else
- rebind_alloc<__node_base>::other
-#endif
- __node_base_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator;
typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer;
__node_base __end_;
@@ -605,8 +592,12 @@
}
void swap(__list_imp& __c)
- _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __list_imp& __c)
@@ -623,24 +614,6 @@
private:
_LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y)
- _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __node_alloc_traits::propagate_on_container_swap::value>());}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<__node_allocator>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__node_allocator& __x, __node_allocator& __y, false_type)
- _NOEXCEPT
- {}
-
- _LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __list_imp& __c, true_type)
{
if (__node_alloc() != __c.__node_alloc())
@@ -740,15 +713,19 @@
template <class _Tp, class _Alloc>
void
__list_imp<_Tp, _Alloc>::swap(__list_imp& __c)
- _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<__node_allocator>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
_LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
this->__node_alloc() == __c.__node_alloc(),
"list::swap: Either propagate_on_container_swap must be true"
" or the allocators must compare equal");
using _VSTD::swap;
- __swap_alloc(__node_alloc(), __c.__node_alloc());
+ __swap_allocator(__node_alloc(), __c.__node_alloc());
swap(__sz(), __c.__sz());
swap(__end_, __c.__end_);
if (__sz() == 0)
@@ -984,8 +961,12 @@
_LIBCPP_INLINE_VISIBILITY
void swap(list& __c)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
_NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value ||
__is_nothrow_swappable<__node_allocator>::value)
+#endif
{base::swap(__c);}
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {base::clear();}
@@ -1480,7 +1461,7 @@
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- for (++__f; __f != __l; ++__f, ++__e, ++__ds)
+ for (++__f; __f != __l; ++__f, (void) ++__e, (void) ++__ds)
{
__hold.reset(__node_alloc_traits::allocate(__na, 1));
__node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f);
diff --git a/include/locale b/include/locale
index 38c68ec..e683ba3 100644
--- a/include/locale
+++ b/include/locale
@@ -198,7 +198,8 @@
// include of <sys/cdefs.h> once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html
// has had a chance to bake for a bit
#include <support/newlib/xlocale.h>
-#elif !defined(__ANDROID__)
+#endif
+#ifdef _LIBCPP_HAS_CATOPEN
#include <nl_types.h>
#endif
@@ -216,7 +217,7 @@
#if defined(__APPLE__) || defined(__FreeBSD__)
# define _LIBCPP_GET_C_LOCALE 0
-#elif defined(__NetBSD__)
+#elif defined(__CloudABI__) || defined(__NetBSD__)
# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE
#else
# define _LIBCPP_GET_C_LOCALE __cloc()
@@ -235,7 +236,7 @@
// locale. Linux, not so much. The following functions avoid the locale when
// that's possible and otherwise do the wrong thing. FIXME.
#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \
- defined(_NEWLIB_VERSION)
+ defined(_NEWLIB_VERSION) || defined(__GLIBC__)
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
@@ -1190,7 +1191,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
#else
- if (__sscanf_l(__buf.c_str(), __cloc(), "%p", &__v) != 1)
+ if (__sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1)
#endif
__err = ios_base::failbit;
// EOF checked
@@ -1560,7 +1561,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+ int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1590,7 +1591,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+ int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1620,7 +1621,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+ int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1650,7 +1651,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+ int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -1682,14 +1683,14 @@
__nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
(int)__iob.precision(), __v);
#else
- __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
- (int)__iob.precision(), __v);
+ __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
+ (int)__iob.precision(), __v);
#endif
else
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
+ __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
unique_ptr<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__nbuf-1))
@@ -1698,14 +1699,13 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
#else
- __nc = __asprintf_l(&__nb, __cloc(), __fmt,
- (int)__iob.precision(), __v);
+ __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
#endif
else
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v);
+ __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
#endif
if (__nb == 0)
__throw_bad_alloc();
@@ -1751,14 +1751,14 @@
__nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
(int)__iob.precision(), __v);
#else
- __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt,
- (int)__iob.precision(), __v);
+ __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt,
+ (int)__iob.precision(), __v);
#endif
else
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v);
+ __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
unique_ptr<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__nbuf-1))
@@ -1767,14 +1767,13 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
#else
- __nc = __asprintf_l(&__nb, __cloc(), __fmt,
- (int)__iob.precision(), __v);
+ __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v);
#endif
else
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v);
+ __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
if (__nb == 0)
__throw_bad_alloc();
@@ -1814,7 +1813,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#else
- int __nc = __snprintf_l(__nar, sizeof(__nar), __cloc(), __fmt, __v);
+ int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
#endif
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
@@ -3527,7 +3526,7 @@
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
__n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units));
#else
- __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units);
+ __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units);
#endif
if (__bb == 0)
__throw_bad_alloc();
@@ -3681,14 +3680,14 @@
typename messages<_CharT>::catalog
messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
{
-#if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION)
- return -1;
-#else // _WIN32 || __ANDROID__
+#ifdef _LIBCPP_HAS_CATOPEN
catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
if (__cat != -1)
__cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1));
return __cat;
-#endif // _WIN32 || __ANDROID__
+#else // !_LIBCPP_HAS_CATOPEN
+ return -1;
+#endif // _LIBCPP_HAS_CATOPEN
}
template <class _CharT>
@@ -3696,9 +3695,7 @@
messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
const string_type& __dflt) const
{
-#if defined(_WIN32) || defined(__ANDROID__) || defined(_NEWLIB_VERSION)
- return __dflt;
-#else // _WIN32
+#ifdef _LIBCPP_HAS_CATOPEN
string __ndflt;
__narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt),
__dflt.c_str(),
@@ -3711,19 +3708,21 @@
__widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w),
__n, __n + strlen(__n));
return __w;
-#endif // _WIN32
+#else // !_LIBCPP_HAS_CATOPEN
+ return __dflt;
+#endif // _LIBCPP_HAS_CATOPEN
}
template <class _CharT>
void
messages<_CharT>::do_close(catalog __c) const
{
-#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION)
+#ifdef _LIBCPP_HAS_CATOPEN
if (__c != -1)
__c <<= 1;
nl_catd __cat = (nl_catd)__c;
catclose(__cat);
-#endif // !_WIN32
+#endif // _LIBCPP_HAS_CATOPEN
}
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>)
diff --git a/include/map b/include/map
index 0b5eb20..eb6b8ed 100644
--- a/include/map
+++ b/include/map
@@ -135,16 +135,32 @@
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type> il);
+ template <class... Args>
+ pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
+ template <class... Args>
+ pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
+ template <class... Args>
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
+ template <class... Args>
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
+ template <class M>
+ pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
+ template <class M>
+ pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
+ template <class M>
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
+ template <class M>
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
+
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(map& m)
- noexcept(
- __is_nothrow_swappable<key_compare>::value &&
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value));
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+ __is_nothrow_swappable<key_compare>::value); // C++17
// observers:
allocator_type get_allocator() const noexcept;
@@ -330,15 +346,14 @@
void insert(initializer_list<value_type> il);
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(multimap& m)
- noexcept(
- __is_nothrow_swappable<key_compare>::value &&
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value));
+ noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+ __is_nothrow_swappable<key_compare>::value); // C++17
// observers:
allocator_type get_allocator() const noexcept;
@@ -426,6 +441,7 @@
#include <utility>
#include <functional>
#include <initializer_list>
+#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -433,10 +449,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value
-#if __has_feature(is_final)
- && !__is_final(_Compare)
-#endif
+template <class _Key, class _CP, class _Compare,
+ bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value
>
class __map_value_compare
: private _Compare
@@ -461,6 +475,12 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _CP& __y) const
{return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);}
+ void swap(__map_value_compare&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
+ {
+ using _VSTD::swap;
+ swap(static_cast<const _Compare&>(*this), static_cast<const _Compare&>(__y));
+ }
#if _LIBCPP_STD_VER > 11
template <typename _K2>
@@ -503,7 +523,13 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _CP& __y) const
{return comp(__x, __y.__cc.first);}
-
+ void swap(__map_value_compare&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value)
+ {
+ using _VSTD::swap;
+ swap(comp, __y.comp);
+ }
+
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
@@ -519,6 +545,16 @@
#endif
};
+template <class _Key, class _CP, class _Compare, bool __b>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x,
+ __map_value_compare<_Key, _CP, _Compare, __b>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+ __x.swap(__y);
+}
+
template <class _Allocator>
class __map_node_destructor
{
@@ -822,13 +858,8 @@
typedef _VSTD::__value_type<key_type, mapped_type> __value_type;
typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__value_type>
-#else
- rebind_alloc<__value_type>::other
-#endif
- __allocator_type;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
+ __value_type>::type __allocator_type;
typedef __tree<__value_type, __vc, __allocator_type> __base;
typedef typename __base::__node_traits __node_traits;
typedef allocator_traits<allocator_type> __alloc_traits;
@@ -1081,9 +1112,125 @@
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_STD_VER > 14
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ return _VSTD::make_pair(__p, false);
+ else
+ return _VSTD::make_pair(
+ emplace_hint(__p,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),
+ true);
+ }
+
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ return _VSTD::make_pair(__p, false);
+ else
+ return _VSTD::make_pair(
+ emplace_hint(__p,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),
+ true);
+ }
+
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ return __p;
+ else
+ return emplace_hint(__p,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
+ }
+
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ return __p;
+ else
+ return emplace_hint(__p,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ {
+ __p->second = _VSTD::forward<_Vp>(__v);
+ return _VSTD::make_pair(__p, false);
+ }
+ return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ {
+ __p->second = _VSTD::forward<_Vp>(__v);
+ return _VSTD::make_pair(__p, false);
+ }
+ return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true);
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ {
+ __p->second = _VSTD::forward<_Vp>(__v);
+ return __p;
+ }
+ return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v));
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v)
+ {
+ iterator __p = lower_bound(__k);
+ if ( __p != end() && !key_comp()(__k, __p->first))
+ {
+ __p->second = _VSTD::forward<_Vp>(__v);
+ return __p;
+ }
+ return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v));
+ }
+#endif
+#endif
+#endif
+
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
_LIBCPP_INLINE_VISIBILITY
+ iterator erase(iterator __p) {return __tree_.erase(__p.__i_);}
+ _LIBCPP_INLINE_VISIBILITY
size_type erase(const key_type& __k)
{return __tree_.__erase_unique(__k);}
_LIBCPP_INLINE_VISIBILITY
@@ -1119,7 +1266,7 @@
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
- count(const _K2& __k) {return __tree_.__count_unique(__k);}
+ count(const _K2& __k) const {return __tree_.__count_unique(__k);}
#endif
_LIBCPP_INLINE_VISIBILITY
iterator lower_bound(const key_type& __k)
@@ -1568,13 +1715,8 @@
typedef _VSTD::__value_type<key_type, mapped_type> __value_type;
typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__value_type>
-#else
- rebind_alloc<__value_type>::other
-#endif
- __allocator_type;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
+ __value_type>::type __allocator_type;
typedef __tree<__value_type, __vc, __allocator_type> __base;
typedef typename __base::__node_traits __node_traits;
typedef allocator_traits<allocator_type> __alloc_traits;
@@ -1821,6 +1963,8 @@
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);}
_LIBCPP_INLINE_VISIBILITY
+ iterator erase(iterator __p) {return __tree_.erase(__p.__i_);}
+ _LIBCPP_INLINE_VISIBILITY
size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);}
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __f, const_iterator __l)
@@ -1855,7 +1999,7 @@
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
- count(const _K2& __k) {return __tree_.__count_multi(__k);}
+ count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif
_LIBCPP_INLINE_VISIBILITY
iterator lower_bound(const key_type& __k)
diff --git a/include/memory b/include/memory
index 7085ced..df35a07 100644
--- a/include/memory
+++ b/include/memory
@@ -75,6 +75,8 @@
| false_type propagate_on_container_move_assignment;
typedef Alloc::propagate_on_container_swap
| false_type propagate_on_container_swap;
+ typedef Alloc::is_always_equal
+ | is_empty is_always_equal;
template <class T> using rebind_alloc = Alloc::rebind<U>::other | Alloc<T, Args...>;
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
@@ -623,6 +625,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _ValueType>
+inline _LIBCPP_ALWAYS_INLINE
+_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
+#if !defined(_LIBCPP_HAS_NO_THREADS) && \
+ defined(__ATOMIC_RELAXED) && \
+ (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407)
+ return __atomic_load_n(__value, __ATOMIC_RELAXED);
+#else
+ return *__value;
+#endif
+}
+
// addressof moved to <__functional_base>
template <class _Tp> class allocator;
@@ -1144,6 +1158,29 @@
typedef typename _Alloc::propagate_on_container_swap type;
};
+template <class _Tp>
+struct __has_is_always_equal
+{
+private:
+ struct __two {char __lx; char __lxx;};
+ template <class _Up> static __two __test(...);
+ template <class _Up> static char __test(typename _Up::is_always_equal* = 0);
+public:
+ static const bool value = sizeof(__test<_Tp>(0)) == 1;
+};
+
+template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
+struct __is_always_equal
+{
+ typedef typename _VSTD::is_empty<_Alloc>::type type;
+};
+
+template <class _Alloc>
+struct __is_always_equal<_Alloc, true>
+{
+ typedef typename _Alloc::is_always_equal type;
+};
+
template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
struct __has_rebind_other
{
@@ -1423,6 +1460,8 @@
propagate_on_container_move_assignment;
typedef typename __propagate_on_container_swap<allocator_type>::type
propagate_on_container_swap;
+ typedef typename __is_always_equal<allocator_type>::type
+ is_always_equal;
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
template <class _Tp> using rebind_alloc =
@@ -1521,8 +1560,42 @@
__construct_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
{
ptrdiff_t _Np = __end1 - __begin1;
- _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
- __begin2 += _Np;
+ if (_Np > 0)
+ {
+ _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
+ __begin2 += _Np;
+ }
+ }
+
+ template <class _Iter, class _Ptr>
+ _LIBCPP_INLINE_VISIBILITY
+ static
+ void
+ __construct_range_forward(allocator_type& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2)
+ {
+ for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
+ construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
+ }
+
+ template <class _Tp>
+ _LIBCPP_INLINE_VISIBILITY
+ static
+ typename enable_if
+ <
+ (is_same<allocator_type, allocator<_Tp> >::value
+ || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
+ is_trivially_move_constructible<_Tp>::value,
+ void
+ >::type
+ __construct_range_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
+ {
+ typedef typename remove_const<_Tp>::type _Vp;
+ ptrdiff_t _Np = __end1 - __begin1;
+ if (_Np > 0)
+ {
+ _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp));
+ __begin2 += _Np;
+ }
}
template <class _Ptr>
@@ -1552,7 +1625,8 @@
{
ptrdiff_t _Np = __end1 - __begin1;
__end2 -= _Np;
- _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
+ if (_Np > 0)
+ _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
}
private:
@@ -1607,6 +1681,16 @@
{return __a;}
};
+template <class _Traits, class _Tp>
+struct __rebind_alloc_helper
+{
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+ typedef typename _Traits::template rebind_alloc<_Tp> type;
+#else
+ typedef typename _Traits::template rebind_alloc<_Tp>::other type;
+#endif
+};
+
// allocator
template <class _Tp>
@@ -1622,6 +1706,7 @@
typedef _Tp value_type;
typedef true_type propagate_on_container_move_assignment;
+ typedef true_type is_always_equal;
template <class _Up> struct rebind {typedef allocator<_Up> other;};
@@ -1714,6 +1799,7 @@
typedef const _Tp value_type;
typedef true_type propagate_on_container_move_assignment;
+ typedef true_type is_always_equal;
template <class _Up> struct rebind {typedef allocator<_Up> other;};
@@ -1817,6 +1903,9 @@
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
_LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int)
{raw_storage_iterator __t(*this); ++__x_; return __t;}
+#if _LIBCPP_STD_VER >= 14
+ _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
+#endif
};
template <class _Tp>
@@ -1906,14 +1995,9 @@
template <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type,
typename remove_cv<_T2>::type>::value,
bool = is_empty<_T1>::value
-#if __has_feature(is_final)
- && !__is_final(_T1)
-#endif
- ,
+ && !__libcpp_is_final<_T1>::value,
bool = is_empty<_T2>::value
-#if __has_feature(is_final)
- && !__is_final(_T2)
-#endif
+ && !__libcpp_is_final<_T2>::value
>
struct __libcpp_compressed_pair_switch;
@@ -1951,11 +2035,11 @@
typedef const typename remove_reference<_T1>::type& _T1_const_reference;
typedef const typename remove_reference<_T2>::type& _T2_const_reference;
- _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+ _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_(), __second_() {}
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
- : __first_(_VSTD::forward<_T1_param>(__t1)) {}
+ : __first_(_VSTD::forward<_T1_param>(__t1)), __second_() {}
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
- : __second_(_VSTD::forward<_T2_param>(__t2)) {}
+ : __first_(), __second_(_VSTD::forward<_T2_param>(__t2)) {}
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
: __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
@@ -2044,9 +2128,9 @@
typedef const _T1& _T1_const_reference;
typedef const typename remove_reference<_T2>::type& _T2_const_reference;
- _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+ _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __second_() {}
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
- : _T1(_VSTD::forward<_T1_param>(__t1)) {}
+ : _T1(_VSTD::forward<_T1_param>(__t1)), __second_() {}
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
: __second_(_VSTD::forward<_T2_param>(__t2)) {}
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
@@ -2134,11 +2218,11 @@
typedef const typename remove_reference<_T1>::type& _T1_const_reference;
typedef const _T2& _T2_const_reference;
- _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
+ _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_() {}
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1)
: __first_(_VSTD::forward<_T1_param>(__t1)) {}
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2)
- : _T2(_VSTD::forward<_T2_param>(__t2)) {}
+ : _T2(_VSTD::forward<_T2_param>(__t2)), __first_() {}
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
is_nothrow_move_constructible<_T2>::value)
@@ -3336,7 +3420,7 @@
{
size_t __a;
size_t __b;
- };
+ } __s;
} __u;
__u.__t = __v;
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
@@ -3358,7 +3442,7 @@
size_t __a;
size_t __b;
size_t __c;
- };
+ } __s;
} __u;
__u.__t = __v;
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
@@ -3381,7 +3465,7 @@
size_t __b;
size_t __c;
size_t __d;
- };
+ } __s;
} __u;
__u.__t = __v;
return __murmur2_or_cityhash<size_t>()(&__u, sizeof(__u));
@@ -3486,8 +3570,8 @@
try
{
#endif
- for (; __f != __l; ++__f, ++__r)
- ::new(&*__r) value_type(*__f);
+ for (; __f != __l; ++__f, (void) ++__r)
+ ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
@@ -3510,8 +3594,8 @@
try
{
#endif
- for (; __n > 0; ++__f, ++__r, --__n)
- ::new(&*__r) value_type(*__f);
+ for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
+ ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
@@ -3535,7 +3619,7 @@
{
#endif
for (; __f != __l; ++__f)
- ::new(&*__f) value_type(__x);
+ ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
@@ -3557,8 +3641,8 @@
try
{
#endif
- for (; __n > 0; ++__f, --__n)
- ::new(&*__f) value_type(__x);
+ for (; __n > 0; ++__f, (void) --__n)
+ ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
@@ -3600,7 +3684,9 @@
void __add_shared() _NOEXCEPT;
bool __release_shared() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
- long use_count() const _NOEXCEPT {return __shared_owners_ + 1;}
+ long use_count() const _NOEXCEPT {
+ return __libcpp_relaxed_load(&__shared_owners_) + 1;
+ }
};
class _LIBCPP_TYPE_VIS __shared_weak_count
@@ -4002,11 +4088,15 @@
__enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT
{
if (__e)
- __e->__weak_this_ = *this;
+ {
+ __e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e));
+ __e->__weak_this_.__cntrl_ = __cntrl_;
+ __cntrl_->__add_weak();
+ }
}
_LIBCPP_INLINE_VISIBILITY
- void __enable_weak_this(const void*) _NOEXCEPT {}
+ void __enable_weak_this(const volatile void*) _NOEXCEPT {}
template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr;
template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr;
@@ -4236,9 +4326,16 @@
>::type)
: __ptr_(__r.get())
{
- typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk;
- __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>());
- __enable_weak_this(__r.get());
+#if _LIBCPP_STD_VER > 11
+ if (__ptr_ == nullptr)
+ __cntrl_ = nullptr;
+ else
+#endif
+ {
+ typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk;
+ __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>());
+ __enable_weak_this(__r.get());
+ }
__r.release();
}
@@ -4258,11 +4355,18 @@
>::type)
: __ptr_(__r.get())
{
- typedef __shared_ptr_pointer<_Yp*,
- reference_wrapper<typename remove_reference<_Dp>::type>,
- allocator<_Yp> > _CntrlBlk;
- __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), allocator<_Yp>());
- __enable_weak_this(__r.get());
+#if _LIBCPP_STD_VER > 11
+ if (__ptr_ == nullptr)
+ __cntrl_ = nullptr;
+ else
+#endif
+ {
+ typedef __shared_ptr_pointer<_Yp*,
+ reference_wrapper<typename remove_reference<_Dp>::type>,
+ allocator<_Yp> > _CntrlBlk;
+ __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), allocator<_Yp>());
+ __enable_weak_this(__r.get());
+ }
__r.release();
}
@@ -5439,6 +5543,38 @@
_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
+// --- Helper for container swap --
+template <typename _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void __swap_allocator(_Alloc & __a1, _Alloc & __a2)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
+#endif
+{
+ __swap_allocator(__a1, __a2,
+ integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
+}
+
+template <typename _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
+#endif
+{
+ using _VSTD::swap;
+ swap(__a1, __a2);
+}
+
+template <typename _Alloc>
+_LIBCPP_INLINE_VISIBILITY
+void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
+
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_MEMORY
diff --git a/include/mutex b/include/mutex
index e2a0daa..373d75b 100644
--- a/include/mutex
+++ b/include/mutex
@@ -175,6 +175,7 @@
#include <__config>
#include <__mutex_base>
#include <functional>
+#include <memory>
#ifndef _LIBCPP_HAS_NO_VARIADICS
#include <tuple>
#endif
@@ -442,7 +443,11 @@
template<class _Callable>
_LIBCPP_INLINE_VISIBILITY
-void call_once(once_flag&, _Callable);
+void call_once(once_flag&, _Callable&);
+
+template<class _Callable>
+_LIBCPP_INLINE_VISIBILITY
+void call_once(once_flag&, const _Callable&);
#endif // _LIBCPP_HAS_NO_VARIADICS
@@ -465,7 +470,11 @@
#else // _LIBCPP_HAS_NO_VARIADICS
template<class _Callable>
friend
- void call_once(once_flag&, _Callable);
+ void call_once(once_flag&, _Callable&);
+
+ template<class _Callable>
+ friend
+ void call_once(once_flag&, const _Callable&);
#endif // _LIBCPP_HAS_NO_VARIADICS
};
@@ -474,15 +483,10 @@
template <class _Fp>
class __call_once_param
{
- _Fp __f_;
+ _Fp& __f_;
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
-#else
- _LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
-#endif
+ explicit __call_once_param(_Fp& __f) : __f_(__f) {}
_LIBCPP_INLINE_VISIBILITY
void operator()()
@@ -496,7 +500,7 @@
_LIBCPP_INLINE_VISIBILITY
void __execute(__tuple_indices<_Indices...>)
{
- __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
+ __invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...);
}
};
@@ -505,15 +509,10 @@
template <class _Fp>
class __call_once_param
{
- _Fp __f_;
+ _Fp& __f_;
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
-#else
- _LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
-#endif
+ explicit __call_once_param(_Fp& __f) : __f_(__f) {}
_LIBCPP_INLINE_VISIBILITY
void operator()()
@@ -541,11 +540,11 @@
void
call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
{
- if (__flag.__state_ != ~0ul)
+ if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul)
{
- typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp;
- __call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)),
- __decay_copy(_VSTD::forward<_Args>(__args))...));
+ 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>);
}
}
@@ -555,15 +554,27 @@
template<class _Callable>
inline _LIBCPP_INLINE_VISIBILITY
void
-call_once(once_flag& __flag, _Callable __func)
+call_once(once_flag& __flag, _Callable& __func)
{
- if (__flag.__state_ != ~0ul)
+ if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul)
{
__call_once_param<_Callable> __p(__func);
__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>);
+ }
+}
+
#endif // _LIBCPP_HAS_NO_VARIADICS
_LIBCPP_END_NAMESPACE_STD
diff --git a/include/new b/include/new
index 29c1a83..d2b2ae6 100644
--- a/include/new
+++ b/include/new
@@ -52,16 +52,12 @@
void operator delete(void* ptr) noexcept; // replaceable
void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14
void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable
-void operator delete(void* ptr, std::size_t size,
- const std::nothrow_t&) noexcept; // replaceable, C++14
void* operator new[](std::size_t size); // replaceable
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable
void operator delete[](void* ptr) noexcept; // replaceable
void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14
void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable
-void operator delete[](void* ptr, std::size_t size,
- const std::nothrow_t&) noexcept; // replaceable, C++14
void* operator new (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;
@@ -140,9 +136,9 @@
_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p) _NOEXCEPT;
_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14
+#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
+ (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)
_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
-_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz, const std::nothrow_t&) _NOEXCEPT;
#endif
_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz)
@@ -153,9 +149,9 @@
_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p) _NOEXCEPT;
_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14
+#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
+ (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)
_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
-_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz, const std::nothrow_t&) _NOEXCEPT;
#endif
inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;}
diff --git a/include/ostream b/include/ostream
index a7af299..f55fd40 100644
--- a/include/ostream
+++ b/include/ostream
@@ -1004,7 +1004,7 @@
basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
{
sentry __s(*this);
- if (__s)
+ if (!this->fail())
{
if (this->rdbuf()->pubseekpos(__pos, ios_base::out) == pos_type(-1))
this->setstate(ios_base::failbit);
@@ -1018,7 +1018,7 @@
basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)
{
sentry __s(*this);
- if (__s)
+ if (!this->fail())
{
if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::out) == pos_type(-1))
this->setstate(ios_base::failbit);
diff --git a/include/random b/include/random
index bccf92a..c8341ef 100644
--- a/include/random
+++ b/include/random
@@ -3475,9 +3475,9 @@
class _LIBCPP_TYPE_VIS random_device
{
-#if !(defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM))
+#ifdef _LIBCPP_USING_DEV_RANDOM
int __f_;
-#endif // !(defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM))
+#endif // defined(_LIBCPP_USING_DEV_RANDOM)
public:
// types
typedef unsigned result_type;
@@ -6044,9 +6044,6 @@
operator>>(basic_istream<_CharT, _Traits>& __is,
discrete_distribution<_IT>& __x)
{
- typedef discrete_distribution<_IT> _Eng;
- typedef typename _Eng::result_type result_type;
- typedef typename _Eng::param_type param_type;
__save_flags<_CharT, _Traits> __lx(__is);
__is.flags(ios_base::dec | ios_base::skipws);
size_t __n;
@@ -6358,7 +6355,6 @@
{
typedef piecewise_constant_distribution<_RT> _Eng;
typedef typename _Eng::result_type result_type;
- typedef typename _Eng::param_type param_type;
__save_flags<_CharT, _Traits> __lx(__is);
__is.flags(ios_base::dec | ios_base::skipws);
size_t __n;
@@ -6698,7 +6694,6 @@
{
typedef piecewise_linear_distribution<_RT> _Eng;
typedef typename _Eng::result_type result_type;
- typedef typename _Eng::param_type param_type;
__save_flags<_CharT, _Traits> __lx(__is);
__is.flags(ios_base::dec | ios_base::skipws);
size_t __n;
diff --git a/include/ratio b/include/ratio
index 48dcd81..f623a06 100644
--- a/include/ratio
+++ b/include/ratio
@@ -21,8 +21,8 @@
class ratio
{
public:
- static const intmax_t num;
- static const intmax_t den;
+ static constexpr intmax_t num;
+ static constexpr intmax_t den;
typedef ratio<num, den> type;
};
@@ -236,19 +236,22 @@
static_assert(__static_abs<_Num>::value >= 0, "ratio numerator is out of range");
static_assert(_Den != 0, "ratio divide by 0");
static_assert(__static_abs<_Den>::value > 0, "ratio denominator is out of range");
- static const intmax_t __na = __static_abs<_Num>::value;
- static const intmax_t __da = __static_abs<_Den>::value;
- static const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;
- static const intmax_t __gcd = __static_gcd<__na, __da>::value;
+ static _LIBCPP_CONSTEXPR const intmax_t __na = __static_abs<_Num>::value;
+ static _LIBCPP_CONSTEXPR const intmax_t __da = __static_abs<_Den>::value;
+ static _LIBCPP_CONSTEXPR const intmax_t __s = __static_sign<_Num>::value * __static_sign<_Den>::value;
+ static _LIBCPP_CONSTEXPR const intmax_t __gcd = __static_gcd<__na, __da>::value;
public:
- static const intmax_t num = __s * __na / __gcd;
- static const intmax_t den = __da / __gcd;
+ static _LIBCPP_CONSTEXPR const intmax_t num = __s * __na / __gcd;
+ static _LIBCPP_CONSTEXPR const intmax_t den = __da / __gcd;
typedef ratio<num, den> type;
};
-template <intmax_t _Num, intmax_t _Den> const intmax_t ratio<_Num, _Den>::num;
-template <intmax_t _Num, intmax_t _Den> const intmax_t ratio<_Num, _Den>::den;
+template <intmax_t _Num, intmax_t _Den>
+_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::num;
+
+template <intmax_t _Num, intmax_t _Den>
+_LIBCPP_CONSTEXPR const intmax_t ratio<_Num, _Den>::den;
template <class _Tp> struct __is_ratio : false_type {};
template <intmax_t _Num, intmax_t _Den> struct __is_ratio<ratio<_Num, _Den> > : true_type {};
@@ -398,11 +401,11 @@
template <class _R1, class _R2>
struct _LIBCPP_TYPE_VIS_ONLY ratio_equal
- : public integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> {};
+ : public _LIBCPP_BOOL_CONSTANT((_R1::num == _R2::num && _R1::den == _R2::den)) {};
template <class _R1, class _R2>
struct _LIBCPP_TYPE_VIS_ONLY ratio_not_equal
- : public integral_constant<bool, !ratio_equal<_R1, _R2>::value> {};
+ : public _LIBCPP_BOOL_CONSTANT((!ratio_equal<_R1, _R2>::value)) {};
// ratio_less
@@ -461,19 +464,19 @@
template <class _R1, class _R2>
struct _LIBCPP_TYPE_VIS_ONLY ratio_less
- : public integral_constant<bool, __ratio_less<_R1, _R2>::value> {};
+ : public _LIBCPP_BOOL_CONSTANT((__ratio_less<_R1, _R2>::value)) {};
template <class _R1, class _R2>
struct _LIBCPP_TYPE_VIS_ONLY ratio_less_equal
- : public integral_constant<bool, !ratio_less<_R2, _R1>::value> {};
+ : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R2, _R1>::value)) {};
template <class _R1, class _R2>
struct _LIBCPP_TYPE_VIS_ONLY ratio_greater
- : public integral_constant<bool, ratio_less<_R2, _R1>::value> {};
+ : public _LIBCPP_BOOL_CONSTANT((ratio_less<_R2, _R1>::value)) {};
template <class _R1, class _R2>
struct _LIBCPP_TYPE_VIS_ONLY ratio_greater_equal
- : public integral_constant<bool, !ratio_less<_R1, _R2>::value> {};
+ : public _LIBCPP_BOOL_CONSTANT((!ratio_less<_R1, _R2>::value)) {};
template <class _R1, class _R2>
struct __ratio_gcd
diff --git a/include/regex b/include/regex
index e1a7f46..c270cab 100644
--- a/include/regex
+++ b/include/regex
@@ -955,6 +955,15 @@
regex_constants::error_type code() const {return __code_;}
};
+template <regex_constants::error_type _Ev>
+_LIBCPP_ALWAYS_INLINE
+void __throw_regex_error()
+{
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw regex_error(_Ev);
+#endif
+}
+
template <class _CharT>
struct _LIBCPP_TYPE_VIS_ONLY regex_traits
{
@@ -1956,7 +1965,8 @@
void
__l_anchor<_CharT>::__exec(__state& __s) const
{
- if (__s.__at_first_ && __s.__current_ == __s.__first_)
+ if (__s.__at_first_ && __s.__current_ == __s.__first_ &&
+ !(__s.__flags_ & regex_constants::match_not_bol))
{
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
@@ -1990,7 +2000,8 @@
void
__r_anchor<_CharT>::__exec(__state& __s) const
{
- if (__s.__current_ == __s.__last_)
+ if (__s.__current_ == __s.__last_ &&
+ !(__s.__flags_ & regex_constants::match_not_eol))
{
__s.__do_ = __state::__accept_but_not_consume;
__s.__node_ = this->first();
@@ -2263,10 +2274,8 @@
}
else
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__b.size() != 1 || __e.size() != 1)
- throw regex_error(regex_constants::error_collate);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_collate>();
if (__icase_)
{
__b[0] = __traits_.translate_nocase(__b[0]);
@@ -2959,7 +2968,7 @@
_LIBCPP_INLINE_VISIBILITY
__lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp)
- : base(__s), __exp_(__exp), __invert_(__invert), __mexp_(__mexp) {}
+ : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {}
virtual void __exec(__state&) const;
};
@@ -3019,10 +3028,8 @@
case egrep:
__first = __parse_egrep(__first, __last);
break;
-#ifndef _LIBCPP_NO_EXCEPTIONS
default:
- throw regex_error(regex_constants::__re_err_grammar);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::__re_err_grammar>();
}
return __first;
}
@@ -3053,10 +3060,8 @@
}
}
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first != __last)
- throw regex_error(regex_constants::__re_err_empty);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::__re_err_empty>();
}
return __first;
}
@@ -3069,19 +3074,15 @@
{
__owns_one_state<_CharT>* __sa = __end_;
_ForwardIterator __temp = __parse_ERE_branch(__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::__re_err_empty);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::__re_err_empty>();
__first = __temp;
while (__first != __last && *__first == '|')
{
__owns_one_state<_CharT>* __sb = __end_;
__temp = __parse_ERE_branch(++__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::__re_err_empty);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::__re_err_empty>();
__push_alternation(__sa, __sb);
__first = __temp;
}
@@ -3095,10 +3096,8 @@
_ForwardIterator __last)
{
_ForwardIterator __temp = __parse_ERE_expression(__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::__re_err_empty);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::__re_err_empty>();
do
{
__first = __temp;
@@ -3133,10 +3132,8 @@
unsigned __temp_count = __marked_count_;
++__open_count_;
__temp = __parse_extended_reg_exp(++__temp, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __last || *__temp != ')')
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
__push_end_marked_subexpression(__temp_count);
--__open_count_;
++__temp;
@@ -3201,10 +3198,8 @@
unsigned __temp_count = __marked_count_;
__first = __parse_RE_expression(__temp, __last);
__temp = __parse_Back_close_paren(__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
__push_end_marked_subexpression(__temp_count);
__first = __temp;
}
@@ -3518,22 +3513,16 @@
int __min = 0;
__first = __temp;
__temp = __parse_DUP_COUNT(__first, __last, __min);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::error_badbrace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_badbrace>();
__first = __temp;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_brace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brace>();
if (*__first != ',')
{
__temp = __parse_Back_close_brace(__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::error_brace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brace>();
__push_loop(__min, __min, __s, __mexp_begin, __mexp_end,
true);
__first = __temp;
@@ -3544,18 +3533,14 @@
int __max = -1;
__first = __parse_DUP_COUNT(__first, __last, __max);
__temp = __parse_Back_close_brace(__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::error_brace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brace>();
if (__max == -1)
__push_greedy_inf_repeat(__min, __s, __mexp_begin, __mexp_end);
else
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__max < __min)
- throw regex_error(regex_constants::error_badbrace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_badbrace>();
__push_loop(__min, __max, __s, __mexp_begin, __mexp_end,
true);
}
@@ -3615,15 +3600,11 @@
{
int __min;
_ForwardIterator __temp = __parse_DUP_COUNT(++__first, __last, __min);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::error_badbrace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_badbrace>();
__first = __temp;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_brace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brace>();
switch (*__first)
{
case '}':
@@ -3638,10 +3619,8 @@
break;
case ',':
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_badbrace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_badbrace>();
if (*__first == '}')
{
++__first;
@@ -3657,20 +3636,14 @@
{
int __max = -1;
__temp = __parse_DUP_COUNT(__first, __last, __max);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __first)
- throw regex_error(regex_constants::error_brace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brace>();
__first = __temp;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last || *__first != '}')
- throw regex_error(regex_constants::error_brace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brace>();
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__max < __min)
- throw regex_error(regex_constants::error_badbrace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_badbrace>();
if (__grammar == ECMAScript && __first != __last && *__first == '?')
{
++__first;
@@ -3680,10 +3653,8 @@
__push_loop(__min, __max, __s, __mexp_begin, __mexp_end);
}
break;
-#ifndef _LIBCPP_NO_EXCEPTIONS
default:
- throw regex_error(regex_constants::error_badbrace);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_badbrace>();
}
}
break;
@@ -3701,10 +3672,8 @@
if (__first != __last && *__first == '[')
{
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
bool __negate = false;
if (*__first == '^')
{
@@ -3713,29 +3682,23 @@
}
__bracket_expression<_CharT, _Traits>* __ml = __start_matching_list(__negate);
// __ml owned by *this
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
if ((__flags_ & 0x1F0) != ECMAScript && *__first == ']')
{
__ml->__add_char(']');
++__first;
}
__first = __parse_follow_list(__first, __last, __ml);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
if (*__first == '-')
{
__ml->__add_char('-');
++__first;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last || *__first != ']')
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
++__first;
}
return __first;
@@ -3855,10 +3818,8 @@
basic_string<_CharT>& __str,
__bracket_expression<_CharT, _Traits>* __ml)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
switch (*__first)
{
case 0:
@@ -3899,10 +3860,8 @@
_ForwardIterator __last,
basic_string<_CharT>* __str)
{
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
switch (*__first)
{
case '\\':
@@ -3970,10 +3929,8 @@
else
__push_char(_CharT(__val));
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
else
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
return __first;
}
@@ -3989,18 +3946,14 @@
value_type _Equal_close[2] = {'=', ']'};
_ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close,
_Equal_close+2);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __last)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
// [__first, __temp) contains all text in [= ... =]
typedef typename _Traits::string_type string_type;
string_type __collate_name =
__traits_.lookup_collatename(__first, __temp);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__collate_name.empty())
- throw regex_error(regex_constants::error_collate);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_collate>();
string_type __equiv_name =
__traits_.transform_primary(__collate_name.begin(),
__collate_name.end());
@@ -4016,10 +3969,8 @@
case 2:
__ml->__add_digraph(__collate_name[0], __collate_name[1]);
break;
-#ifndef _LIBCPP_NO_EXCEPTIONS
default:
- throw regex_error(regex_constants::error_collate);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_collate>();
}
}
__first = _VSTD::next(__temp, 2);
@@ -4038,18 +3989,14 @@
value_type _Colon_close[2] = {':', ']'};
_ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close,
_Colon_close+2);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __last)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
// [__first, __temp) contains all text in [: ... :]
typedef typename _Traits::char_class_type char_class_type;
char_class_type __class_type =
__traits_.lookup_classname(__first, __temp, __flags_ & icase);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__class_type == 0)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
__ml->__add_class(__class_type);
__first = _VSTD::next(__temp, 2);
return __first;
@@ -4067,22 +4014,17 @@
value_type _Dot_close[2] = {'.', ']'};
_ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close,
_Dot_close+2);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __last)
- throw regex_error(regex_constants::error_brack);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_brack>();
// [__first, __temp) contains all text in [. ... .]
- typedef typename _Traits::string_type string_type;
__col_sym = __traits_.lookup_collatename(__first, __temp);
switch (__col_sym.size())
{
case 1:
case 2:
break;
-#ifndef _LIBCPP_NO_EXCEPTIONS
default:
- throw regex_error(regex_constants::error_collate);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_collate>();
}
__first = _VSTD::next(__temp, 2);
return __first;
@@ -4226,10 +4168,8 @@
unsigned __mexp = __exp.__marked_count_;
__push_lookahead(_VSTD::move(__exp), false, __marked_count_);
__marked_count_ += __mexp;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __last || *__temp != ')')
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
__first = ++__temp;
}
break;
@@ -4241,10 +4181,8 @@
unsigned __mexp = __exp.__marked_count_;
__push_lookahead(_VSTD::move(__exp), true, __marked_count_);
__marked_count_ += __mexp;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__temp == __last || *__temp != ')')
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
__first = ++__temp;
}
break;
@@ -4281,19 +4219,15 @@
case '(':
{
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
_ForwardIterator __temp = _VSTD::next(__first);
if (__temp != __last && *__first == '?' && *__temp == ':')
{
++__open_count_;
__first = __parse_ecma_exp(++__temp, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last || *__first != ')')
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
--__open_count_;
++__first;
}
@@ -4303,16 +4237,20 @@
unsigned __temp_count = __marked_count_;
++__open_count_;
__first = __parse_ecma_exp(__first, __last);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last || *__first != ')')
- throw regex_error(regex_constants::error_paren);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_paren>();
__push_end_marked_subexpression(__temp_count);
--__open_count_;
++__first;
}
}
break;
+ case '*':
+ case '+':
+ case '?':
+ case '{':
+ __throw_regex_error<regex_constants::error_badrepeat>();
+ break;
default:
__first = __parse_pattern_character(__first, __last);
break;
@@ -4367,10 +4305,8 @@
unsigned __v = *__first - '0';
for (++__first; '0' <= *__first && *__first <= '9'; ++__first)
__v = 10 * __v + *__first - '0';
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__v > mark_count())
- throw regex_error(regex_constants::error_backref);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_backref>();
__push_back_ref(__v);
}
}
@@ -4486,62 +4422,42 @@
__push_char(_CharT(*__t % 32));
__first = ++__t;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
else
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
else
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
break;
case 'u':
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__hd = __traits_.value(*__first, 16);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__hd == -1)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__sum = 16 * __sum + static_cast<unsigned>(__hd);
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__hd = __traits_.value(*__first, 16);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__hd == -1)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__sum = 16 * __sum + static_cast<unsigned>(__hd);
// drop through
case 'x':
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__hd = __traits_.value(*__first, 16);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__hd == -1)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__sum = 16 * __sum + static_cast<unsigned>(__hd);
++__first;
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__first == __last)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__hd = __traits_.value(*__first, 16);
-#ifndef _LIBCPP_NO_EXCEPTIONS
if (__hd == -1)
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
__sum = 16 * __sum + static_cast<unsigned>(__hd);
if (__str)
*__str = _CharT(__sum);
@@ -4565,10 +4481,8 @@
__push_char(*__first);
++__first;
}
-#ifndef _LIBCPP_NO_EXCEPTIONS
else
- throw regex_error(regex_constants::error_escape);
-#endif // _LIBCPP_NO_EXCEPTIONS
+ __throw_regex_error<regex_constants::error_escape>();
break;
}
}
@@ -5429,8 +5343,8 @@
__unmatched_(),
__prefix_(),
__suffix_(),
- __position_start_(),
- __ready_(false)
+ __ready_(false),
+ __position_start_()
{
}
@@ -5655,9 +5569,7 @@
__states.pop_back();
break;
default:
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw regex_error(regex_constants::__re_err_unknown);
-#endif
+ __throw_regex_error<regex_constants::__re_err_unknown>();
break;
}
@@ -5727,9 +5639,7 @@
__states.pop_back();
break;
default:
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw regex_error(regex_constants::__re_err_unknown);
-#endif
+ __throw_regex_error<regex_constants::__re_err_unknown>();
break;
}
} while (!__states.empty());
@@ -5815,9 +5725,7 @@
__states.pop_back();
break;
default:
-#ifndef _LIBCPP_NO_EXCEPTIONS
- throw regex_error(regex_constants::__re_err_unknown);
-#endif
+ __throw_regex_error<regex_constants::__re_err_unknown>();
break;
}
} while (!__states.empty());
diff --git a/include/scoped_allocator b/include/scoped_allocator
index aa8bece..cd4987a 100644
--- a/include/scoped_allocator
+++ b/include/scoped_allocator
@@ -38,6 +38,7 @@
typedef see below propagate_on_container_copy_assignment;
typedef see below propagate_on_container_move_assignment;
typedef see below propagate_on_container_swap;
+ typedef see below is_always_equal;
template <class Tp>
struct rebind
@@ -170,6 +171,22 @@
__get_poc_swap<_Allocs...>::value;
};
+template <class ..._Allocs> struct __get_is_always_equal;
+
+template <class _A0>
+struct __get_is_always_equal<_A0>
+{
+ static const bool value = allocator_traits<_A0>::is_always_equal::value;
+};
+
+template <class _A0, class ..._Allocs>
+struct __get_is_always_equal<_A0, _Allocs...>
+{
+ static const bool value =
+ allocator_traits<_A0>::is_always_equal::value &&
+ __get_is_always_equal<_Allocs...>::value;
+};
+
template <class ..._Allocs>
class __scoped_allocator_storage;
@@ -397,6 +414,11 @@
bool,
__get_poc_swap<outer_allocator_type, _InnerAllocs...>::value
> propagate_on_container_swap;
+ typedef integral_constant
+ <
+ bool,
+ __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value
+ > is_always_equal;
template <class _Tp>
struct rebind
diff --git a/include/set b/include/set
index 22d794d..9d64a52 100644
--- a/include/set
+++ b/include/set
@@ -116,6 +116,7 @@
void insert(initializer_list<value_type> il);
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -297,6 +298,7 @@
void insert(initializer_list<value_type> il);
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
diff --git a/include/shared_mutex b/include/shared_mutex
index 9b7f0bf..dcb9394 100644
--- a/include/shared_mutex
+++ b/include/shared_mutex
@@ -19,6 +19,29 @@
namespace std
{
+class shared_mutex // C++17
+{
+public:
+ shared_mutex();
+ ~shared_mutex();
+
+ shared_mutex(const shared_mutex&) = delete;
+ shared_mutex& operator=(const shared_mutex&) = delete;
+
+ // Exclusive ownership
+ void lock(); // blocking
+ bool try_lock();
+ void unlock();
+
+ // Shared ownership
+ void lock_shared(); // blocking
+ bool try_lock_shared();
+ void unlock_shared();
+
+ typedef implementation-defined native_handle_type; // See 30.2.3
+ native_handle_type native_handle(); // See 30.2.3
+};
+
class shared_timed_mutex
{
public:
@@ -118,7 +141,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-class _LIBCPP_TYPE_VIS shared_timed_mutex
+struct _LIBCPP_TYPE_VIS __shared_mutex_base
{
mutex __mut_;
condition_variable __gate1_;
@@ -127,6 +150,58 @@
static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1);
static const unsigned __n_readers_ = ~__write_entered_;
+
+ __shared_mutex_base();
+ _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default;
+
+ __shared_mutex_base(const __shared_mutex_base&) = delete;
+ __shared_mutex_base& operator=(const __shared_mutex_base&) = delete;
+
+ // Exclusive ownership
+ void lock(); // blocking
+ bool try_lock();
+ void unlock();
+
+ // Shared ownership
+ void lock_shared(); // blocking
+ bool try_lock_shared();
+ void unlock_shared();
+
+// typedef implementation-defined native_handle_type; // See 30.2.3
+// native_handle_type native_handle(); // See 30.2.3
+};
+
+
+#if _LIBCPP_STD_VER > 14
+class _LIBCPP_TYPE_VIS shared_mutex
+{
+ __shared_mutex_base __base;
+public:
+ shared_mutex() : __base() {}
+ _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
+
+ shared_mutex(const shared_mutex&) = delete;
+ shared_mutex& operator=(const shared_mutex&) = delete;
+
+ // Exclusive ownership
+ _LIBCPP_INLINE_VISIBILITY void lock() { return __base.lock(); }
+ _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base.try_lock(); }
+ _LIBCPP_INLINE_VISIBILITY void unlock() { return __base.unlock(); }
+
+ // Shared ownership
+ _LIBCPP_INLINE_VISIBILITY void lock_shared() { return __base.lock_shared(); }
+ _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base.try_lock_shared(); }
+ _LIBCPP_INLINE_VISIBILITY void unlock_shared() { return __base.unlock_shared(); }
+
+// typedef __shared_mutex_base::native_handle_type native_handle_type;
+// _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); }
+};
+#endif
+
+
+class _LIBCPP_TYPE_VIS shared_timed_mutex
+{
+ __shared_mutex_base __base;
public:
shared_timed_mutex();
_LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default;
@@ -170,29 +245,30 @@
shared_timed_mutex::try_lock_until(
const chrono::time_point<_Clock, _Duration>& __abs_time)
{
- unique_lock<mutex> __lk(__mut_);
- if (__state_ & __write_entered_)
+ unique_lock<mutex> __lk(__base.__mut_);
+ if (__base.__state_ & __base.__write_entered_)
{
while (true)
{
- cv_status __status = __gate1_.wait_until(__lk, __abs_time);
- if ((__state_ & __write_entered_) == 0)
+ cv_status __status = __base.__gate1_.wait_until(__lk, __abs_time);
+ if ((__base.__state_ & __base.__write_entered_) == 0)
break;
if (__status == cv_status::timeout)
return false;
}
}
- __state_ |= __write_entered_;
- if (__state_ & __n_readers_)
+ __base.__state_ |= __base.__write_entered_;
+ if (__base.__state_ & __base.__n_readers_)
{
while (true)
{
- cv_status __status = __gate2_.wait_until(__lk, __abs_time);
- if ((__state_ & __n_readers_) == 0)
+ cv_status __status = __base.__gate2_.wait_until(__lk, __abs_time);
+ if ((__base.__state_ & __base.__n_readers_) == 0)
break;
if (__status == cv_status::timeout)
{
- __state_ &= ~__write_entered_;
+ __base.__state_ &= ~__base.__write_entered_;
+ __base.__gate1_.notify_all();
return false;
}
}
@@ -205,22 +281,22 @@
shared_timed_mutex::try_lock_shared_until(
const chrono::time_point<_Clock, _Duration>& __abs_time)
{
- unique_lock<mutex> __lk(__mut_);
- if ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
+ unique_lock<mutex> __lk(__base.__mut_);
+ if ((__base.__state_ & __base.__write_entered_) || (__base.__state_ & __base.__n_readers_) == __base.__n_readers_)
{
while (true)
{
- cv_status status = __gate1_.wait_until(__lk, __abs_time);
- if ((__state_ & __write_entered_) == 0 &&
- (__state_ & __n_readers_) < __n_readers_)
+ cv_status status = __base.__gate1_.wait_until(__lk, __abs_time);
+ if ((__base.__state_ & __base.__write_entered_) == 0 &&
+ (__base.__state_ & __base.__n_readers_) < __base.__n_readers_)
break;
if (status == cv_status::timeout)
return false;
}
}
- unsigned __num_readers = (__state_ & __n_readers_) + 1;
- __state_ &= ~__n_readers_;
- __state_ |= __num_readers;
+ unsigned __num_readers = (__base.__state_ & __base.__n_readers_) + 1;
+ __base.__state_ &= ~__base.__n_readers_;
+ __base.__state_ |= __num_readers;
return true;
}
diff --git a/include/string b/include/string
index 840932a..2c677ce 100644
--- a/include/string
+++ b/include/string
@@ -220,8 +220,8 @@
basic_string substr(size_type pos = 0, size_type n = npos) const;
void swap(basic_string& str)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+ noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
const value_type* c_str() const noexcept;
const value_type* data() const noexcept;
@@ -742,7 +742,7 @@
static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
- {return int_type(0xDFFF);}
+ {return int_type(0xFFFF);}
};
inline _LIBCPP_INLINE_VISIBILITY
@@ -1322,13 +1322,26 @@
_LIBCPP_INLINE_VISIBILITY basic_string()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
- _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a);
+
+ _LIBCPP_INLINE_VISIBILITY explicit basic_string(const allocator_type& __a)
+#if _LIBCPP_STD_VER <= 14
+ _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
+#else
+ _NOEXCEPT;
+#endif
+
basic_string(const basic_string& __str);
basic_string(const basic_string& __str, const allocator_type& __a);
+
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
basic_string(basic_string&& __str)
+#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+#else
+ _NOEXCEPT;
+#endif
+
_LIBCPP_INLINE_VISIBILITY
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1591,8 +1604,12 @@
_LIBCPP_INLINE_VISIBILITY
void swap(basic_string& __str)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
_LIBCPP_INLINE_VISIBILITY
const value_type* c_str() const _NOEXCEPT {return data();}
@@ -1855,24 +1872,6 @@
_NOEXCEPT
{}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type&, allocator_type&, false_type) _NOEXCEPT
- {}
-
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
@@ -1937,7 +1936,12 @@
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a)
- : __r_(__a)
+#if _LIBCPP_STD_VER <= 14
+ _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
+#else
+ _NOEXCEPT
+#endif
+: __r_(__a)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
@@ -2070,7 +2074,11 @@
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str)
+#if _LIBCPP_STD_VER <= 14
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+#else
+ _NOEXCEPT
+#endif
: __r_(_VSTD::move(__str.__r_))
{
__str.__zero();
@@ -3349,8 +3357,12 @@
inline _LIBCPP_INLINE_VISIBILITY
void
basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
#if _LIBCPP_DEBUG_LEVEL >= 2
if (!__is_long())
@@ -3360,7 +3372,7 @@
__get_db()->swap(this, &__str);
#endif
_VSTD::swap(__r_.first(), __str.__r_.first());
- __swap_alloc(__alloc(), __str.__alloc());
+ __swap_allocator(__alloc(), __str.__alloc());
}
// find
diff --git a/include/tuple b/include/tuple
index 21fa900..3a22aa5 100644
--- a/include/tuple
+++ b/include/tuple
@@ -161,10 +161,8 @@
// __tuple_leaf
-template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
-#if __has_feature(is_final)
- && !__is_final(_Hp)
-#endif
+template <size_t _Ip, class _Hp,
+ bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
>
class __tuple_leaf;
@@ -846,8 +844,6 @@
namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
-template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
-
template <class _Tp>
struct __make_tuple_return_impl
{
diff --git a/include/type_traits b/include/type_traits
index 1820bb2..f0defaf 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -19,8 +19,13 @@
// helper class:
template <class T, T v> struct integral_constant;
- typedef integral_constant<bool, true> true_type;
- typedef integral_constant<bool, false> false_type;
+ 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;
@@ -211,10 +216,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-template <class...>
+template <class>
struct __void_t { typedef void type; };
-#endif
+
+template <class _Tp>
+struct __identity { typedef _Tp type; };
template <class _Tp, bool>
struct _LIBCPP_TYPE_VIS_ONLY __dependent_type : public _Tp {};
@@ -260,8 +266,16 @@
template <class _Tp, _Tp __v>
_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value;
-typedef integral_constant<bool, true> true_type;
-typedef integral_constant<bool, false> false_type;
+#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
@@ -460,25 +474,21 @@
// template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {};
//
-template <class _MP, bool _IsMemberFuctionPtr, bool _IsMemberObjectPtr>
+template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
struct __member_pointer_traits_imp
{ // forward declaration; specializations later
};
-namespace __libcpp_is_member_function_pointer_imp {
- template <typename _Tp>
- char __test(typename std::__member_pointer_traits_imp<_Tp, true, false>::_FnType *);
-
- template <typename>
- std::__two __test(...);
-};
-
template <class _Tp> struct __libcpp_is_member_function_pointer
- : public integral_constant<bool, sizeof(__libcpp_is_member_function_pointer_imp::__test<_Tp>(nullptr)) == 1> {};
+ : 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> {};
+ : public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type>::type {};
// is_member_pointer
@@ -679,7 +689,7 @@
// is_signed
template <class _Tp, bool = is_integral<_Tp>::value>
-struct __libcpp_is_signed_impl : public integral_constant<bool, _Tp(-1) < _Tp(0)> {};
+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
@@ -694,7 +704,7 @@
// is_unsigned
template <class _Tp, bool = is_integral<_Tp>::value>
-struct __libcpp_is_unsigned_impl : public integral_constant<bool, _Tp(0) < _Tp(-1)> {};
+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
@@ -796,8 +806,16 @@
// is_final
-#if _LIBCPP_STD_VER > 11 && __has_feature(is_final)
-template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
+#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
@@ -838,7 +856,7 @@
// is_convertible
-#if __has_feature(is_convertible_to)
+#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) &&
@@ -848,7 +866,16 @@
namespace __is_convertible_imp
{
-template <class _Tp> char __test(_Tp);
+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();
@@ -883,10 +910,8 @@
unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value>
struct __is_convertible
: public integral_constant<bool,
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1
-#else
- sizeof(__is_convertible_imp::__test<_T2>(__is_convertible_imp::__source<_T1>())) == 1
+ __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)
@@ -900,6 +925,7 @@
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 {};
@@ -1525,7 +1551,7 @@
struct __is_assignable_imp
: public common_type
<
- decltype(__is_assignable_test(declval<_Tp>(), declval<_Arg>()))
+ decltype(_VSTD::__is_assignable_test(declval<_Tp>(), declval<_Arg>()))
>::type {};
template <class _Tp, class _Arg>
@@ -1772,7 +1798,8 @@
typedef _Rp (_FnType) (_Param..., ...);
};
-#if __has_feature(cxx_reference_qualified_functions)
+#if __has_feature(cxx_reference_qualified_functions) || \
+ (defined(_GNUC_VER) && _GNUC_VER >= 409)
template <class _Rp, class _Class, class ..._Param>
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
@@ -1902,7 +1929,7 @@
typedef _Rp (_FnType) (_Param..., ...);
};
-#endif // __has_feature(cxx_reference_qualified_functions)
+#endif // __has_feature(cxx_reference_qualified_functions) || _GNUC_VER >= 409
#else // _LIBCPP_HAS_NO_VARIADICS
@@ -2228,7 +2255,7 @@
template <class _MP, class _Tp>
struct __result_of_mp<_MP, _Tp, true>
- : public common_type<typename __member_pointer_traits<_MP>::_ReturnType>
+ : public __identity<typename __member_pointer_traits<_MP>::_ReturnType>
{
};
@@ -2296,7 +2323,7 @@
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn()>
: public __result_of<_Fn(),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_reference<_Fn>::type>::value,
+ is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
@@ -2306,7 +2333,7 @@
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0)>
: public __result_of<_Fn(_A0),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_reference<_Fn>::type>::value,
+ is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
@@ -2316,7 +2343,7 @@
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1)>
: public __result_of<_Fn(_A0, _A1),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_reference<_Fn>::type>::value,
+ is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
@@ -2326,7 +2353,7 @@
class _LIBCPP_TYPE_VIS_ONLY result_of<_Fn(_A0, _A1, _A2)>
: public __result_of<_Fn(_A0, _A1, _A2),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_reference<_Fn>::type>::value,
+ is_function<typename remove_pointer<typename remove_reference<_Fn>::type>::type>::value,
is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
@@ -2674,7 +2701,7 @@
#ifndef _LIBCPP_HAS_NO_VARIADICS
-#if __has_feature(is_trivially_constructible)
+#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501
template <class _Tp, class... _Args>
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible
@@ -2733,7 +2760,7 @@
{
};
-#if __has_feature(is_trivially_constructible)
+#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501
template <class _Tp>
struct _LIBCPP_TYPE_VIS_ONLY is_trivially_constructible<_Tp, __is_construct::__nat,
@@ -2821,7 +2848,7 @@
// is_trivially_assignable
-#if __has_feature(is_trivially_assignable)
+#if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501
template <class _Tp, class _Arg>
struct is_trivially_assignable
@@ -2890,6 +2917,9 @@
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible
: public __libcpp_trivial_destructor<typename remove_all_extents<_Tp>::type> {};
+template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_destructible<_Tp[]>
+ : public false_type {};
+
#endif
// is_nothrow_constructible
@@ -3214,6 +3244,10 @@
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible
: public __libcpp_nothrow_destructor<typename remove_all_extents<_Tp>::type> {};
+template <class _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_destructible<_Tp[]>
+ : public false_type {};
+
#endif
// is_pod
@@ -3259,6 +3293,8 @@
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copyable
#if __has_feature(is_trivially_copyable)
: public integral_constant<bool, __is_trivially_copyable(_Tp)>
+#elif _GNUC_VER >= 501
+ : public integral_constant<bool, !is_volatile<_Tp>::value && __is_trivially_copyable(_Tp)>
#else
: integral_constant<bool, is_scalar<typename remove_all_extents<_Tp>::type>::value>
#endif
@@ -3267,7 +3303,7 @@
// is_trivial;
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivial
-#if __has_feature(is_trivial) || (_GNUC_VER >= 407)
+#if __has_feature(is_trivial) || _GNUC_VER >= 407
: public integral_constant<bool, __is_trivial(_Tp)>
#else
: integral_constant<bool, is_trivially_copyable<_Tp>::value &&
diff --git a/include/unordered_map b/include/unordered_map
index 0fa87d1..cf70ab6 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -122,7 +122,25 @@
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
+ template <class... Args>
+ pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
+ template <class... Args>
+ pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
+ template <class... Args>
+ iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
+ template <class... Args>
+ iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
+ template <class M>
+ pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
+ template <class M>
+ pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
+ template <class M>
+ iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
+ template <class M>
+ iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
+
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -287,6 +305,7 @@
void insert(initializer_list<value_type>);
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
@@ -359,10 +378,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value
-#if __has_feature(is_final)
- && !__is_final(_Hash)
-#endif
+template <class _Key, class _Cp, class _Hash,
+ bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
>
class __unordered_map_hasher
: private _Hash
@@ -384,6 +401,12 @@
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const _Key& __x) const
{return static_cast<const _Hash&>(*this)(__x);}
+ void swap(__unordered_map_hasher&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)
+ {
+ using _VSTD::swap;
+ swap(static_cast<const _Hash&>(*this), static_cast<const _Hash&>(__y));
+ }
};
template <class _Key, class _Cp, class _Hash>
@@ -408,12 +431,26 @@
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const _Key& __x) const
{return __hash_(__x);}
+ void swap(__unordered_map_hasher&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Hash>::value)
+ {
+ using _VSTD::swap;
+ swap(__hash_, __y.__hash_);
+ }
};
-template <class _Key, class _Cp, class _Pred, bool = is_empty<_Pred>::value
-#if __has_feature(is_final)
- && !__is_final(_Pred)
-#endif
+template <class _Key, class _Cp, class _Hash, bool __b>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x,
+ __unordered_map_hasher<_Key, _Cp, _Hash, __b>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+ __x.swap(__y);
+}
+
+template <class _Key, class _Cp, class _Pred,
+ bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
>
class __unordered_map_equal
: private _Pred
@@ -438,6 +475,12 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _Cp& __y) const
{return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);}
+ void swap(__unordered_map_equal&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
+ {
+ using _VSTD::swap;
+ swap(static_cast<const _Pred&>(*this), static_cast<const _Pred&>(__y));
+ }
};
template <class _Key, class _Cp, class _Pred>
@@ -465,8 +508,24 @@
_LIBCPP_INLINE_VISIBILITY
bool operator()(const _Key& __x, const _Cp& __y) const
{return __pred_(__x, __y.__cc.first);}
+ void swap(__unordered_map_equal&__y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value)
+ {
+ using _VSTD::swap;
+ swap(__pred_, __y.__pred_);
+ }
};
+template <class _Key, class _Cp, class _Pred, bool __b>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+swap(__unordered_map_equal<_Key, _Cp, _Pred, __b>& __x,
+ __unordered_map_equal<_Key, _Cp, _Pred, __b>& __y)
+ _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
+{
+ __x.swap(__y);
+}
+
template <class _Alloc>
class __hash_map_node_destructor
{
@@ -551,7 +610,7 @@
_LIBCPP_INLINE_VISIBILITY
__hash_value_type(__hash_value_type&& __v)
- : __nc(std::move(__v.__nc)) {}
+ : __nc(_VSTD::move(__v.__nc)) {}
_LIBCPP_INLINE_VISIBILITY
__hash_value_type& operator=(const __hash_value_type& __v)
@@ -559,7 +618,7 @@
_LIBCPP_INLINE_VISIBILITY
__hash_value_type& operator=(__hash_value_type&& __v)
- {__nc = std::move(__v.__nc); return *this;}
+ {__nc = _VSTD::move(__v.__nc); return *this;}
_LIBCPP_INLINE_VISIBILITY
~__hash_value_type() {__cc.~value_type();}
@@ -730,13 +789,8 @@
typedef __hash_value_type<key_type, mapped_type> __value_type;
typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher;
typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__value_type>
-#else
- rebind_alloc<__value_type>::other
-#endif
- __allocator_type;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
+ __value_type>::type __allocator_type;
typedef __hash_table<__value_type, __hasher,
__key_equal, __allocator_type> __table;
@@ -946,9 +1000,125 @@
{insert(__il.begin(), __il.end());}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+#if _LIBCPP_STD_VER > 14
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ return _VSTD::make_pair(__p, false);
+ else
+ return _VSTD::make_pair(
+ emplace_hint(__p,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),
+ true);
+ }
+
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ return _VSTD::make_pair(__p, false);
+ else
+ return _VSTD::make_pair(
+ emplace_hint(__p,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)),
+ true);
+ }
+
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ return __p;
+ else
+ return emplace_hint(__h,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
+ }
+
+ template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ return __p;
+ else
+ return emplace_hint(__h,
+ _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)),
+ _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...));
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ {
+ __p->second = _VSTD::move(__v);
+ return _VSTD::make_pair(__p, false);
+ }
+ return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true);
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ {
+ __p->second = _VSTD::move(__v);
+ return _VSTD::make_pair(__p, false);
+ }
+ return _VSTD::make_pair(emplace_hint(__p, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v)), true);
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ {
+ __p->second = _VSTD::move(__v);
+ return __p;
+ }
+ return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v));
+ }
+
+ template <class _Vp>
+ _LIBCPP_INLINE_VISIBILITY
+ iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v)
+ {
+ iterator __p = __table_.find(__k);
+ if ( __p != end())
+ {
+ __p->second = _VSTD::move(__v);
+ return __p;
+ }
+ return emplace_hint(__h, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v));
+ }
+#endif
+#endif
+#endif
+
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
_LIBCPP_INLINE_VISIBILITY
+ iterator erase(iterator __p) {return __table_.erase(__p.__i_);}
+ _LIBCPP_INLINE_VISIBILITY
size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);}
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __first, const_iterator __last)
@@ -1469,13 +1639,8 @@
typedef __hash_value_type<key_type, mapped_type> __value_type;
typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher;
typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
- typedef typename allocator_traits<allocator_type>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__value_type>
-#else
- rebind_alloc<__value_type>::other
-#endif
- __allocator_type;
+ typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
+ __value_type>::type __allocator_type;
typedef __hash_table<__value_type, __hasher,
__key_equal, __allocator_type> __table;
@@ -1654,6 +1819,8 @@
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}
_LIBCPP_INLINE_VISIBILITY
+ iterator erase(iterator __p) {return __table_.erase(__p.__i_);}
+ _LIBCPP_INLINE_VISIBILITY
size_type erase(const key_type& __k) {return __table_.__erase_multi(__k);}
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __first, const_iterator __last)
diff --git a/include/unordered_set b/include/unordered_set
index d06629f..f6ccdc3 100644
--- a/include/unordered_set
+++ b/include/unordered_set
@@ -114,16 +114,15 @@
void insert(initializer_list<value_type>);
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(unordered_set&)
- noexcept(
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value);
+ noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+ noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
+ noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17
hasher hash_function() const;
key_equal key_eq() const;
@@ -263,16 +262,15 @@
void insert(initializer_list<value_type>);
iterator erase(const_iterator position);
+ iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void clear() noexcept;
void swap(unordered_multiset&)
- noexcept(
- (!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value) &&
- __is_nothrow_swappable<hasher>::value &&
- __is_nothrow_swappable<key_equal>::value);
+ noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+ noexcept(swap(declval<hasher&>(), declval<hasher&>())) &&
+ noexcept(swap(declval<key_equal&>(), declval<key_equal&>()))); // C++17
hasher hash_function() const;
key_equal key_eq() const;
diff --git a/include/utility b/include/utility
index 96db60a..54cfc8b 100644
--- a/include/utility
+++ b/include/utility
@@ -513,10 +513,6 @@
: public integral_constant<size_t, 2> {};
template <class _T1, class _T2>
- class _LIBCPP_TYPE_VIS_ONLY tuple_size<const pair<_T1, _T2> >
- : public integral_constant<size_t, 2> {};
-
-template <class _T1, class _T2>
class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, pair<_T1, _T2> >
{
public:
@@ -530,20 +526,6 @@
typedef _T2 type;
};
-template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, const pair<_T1, _T2> >
-{
-public:
- typedef const _T1 type;
-};
-
-template <class _T1, class _T2>
-class _LIBCPP_TYPE_VIS_ONLY tuple_element<1, const pair<_T1, _T2> >
-{
-public:
- typedef const _T2 type;
-};
-
template <size_t _Ip> struct __get_pair;
template <>
diff --git a/include/vector b/include/vector
index 22a6343..049d3c8 100644
--- a/include/vector
+++ b/include/vector
@@ -119,8 +119,8 @@
void resize(size_type sz, const value_type& c);
void swap(vector&)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
bool __invariants() const;
};
@@ -237,8 +237,8 @@
void resize(size_type sz, value_type x);
void swap(vector&)
- noexcept(!allocator_type::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+ noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
+ allocator_traits<allocator_type>::is_always_equal::value); // C++17
void flip() noexcept;
bool __invariants() const;
@@ -385,14 +385,6 @@
is_nothrow_move_assignable<allocator_type>::value)
{__move_assign_alloc(__c, integral_constant<bool,
__alloc_traits::propagate_on_container_move_assignment::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y)
- _NOEXCEPT_(
- !__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __alloc_traits::propagate_on_container_swap::value>());}
private:
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const __vector_base& __c, true_type)
@@ -421,18 +413,6 @@
void __move_assign_alloc(__vector_base&, false_type)
_NOEXCEPT
{}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type& __x, allocator_type& __y, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(allocator_type&, allocator_type&, false_type)
- _NOEXCEPT
- {}
};
template <class _Tp, class _Allocator>
@@ -500,14 +480,18 @@
"Allocator::value_type must be same type as value_type");
_LIBCPP_INLINE_VISIBILITY
- vector()
- _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+ vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
}
_LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
+#if _LIBCPP_STD_VER <= 14
+ _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
+#else
+ _NOEXCEPT
+#endif
: __base(__a)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -569,7 +553,11 @@
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
vector(vector&& __x)
+#if _LIBCPP_STD_VER > 14
+ _NOEXCEPT;
+#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+#endif
_LIBCPP_INLINE_VISIBILITY
vector(vector&& __x, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
@@ -756,8 +744,12 @@
void resize(size_type __sz, const_reference __x);
void swap(vector&)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
bool __invariants() const;
@@ -783,7 +775,7 @@
__is_forward_iterator<_ForwardIterator>::value,
void
>::type
- __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
+ __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n);
void __append(size_type __n);
void __append(size_type __n, const_reference __x);
_LIBCPP_INLINE_VISIBILITY
@@ -868,17 +860,17 @@
// but if an exception is thrown after that the annotation has to be undone.
struct __RAII_IncreaseAnnotator {
__RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)
- : __commit(false), __v(__v), __n(__n) {
+ : __commit(false), __v(__v), __old_size(__v.size() + __n) {
__v.__annotate_increase(__n);
}
void __done() { __commit = true; }
~__RAII_IncreaseAnnotator() {
if (__commit) return;
- __v.__annotate_shrink(__v.size() + __n);
+ __v.__annotate_shrink(__old_size);
}
bool __commit;
- size_type __n;
const vector &__v;
+ size_type __old_size;
};
#else
struct __RAII_IncreaseAnnotator {
@@ -1021,16 +1013,12 @@
__is_forward_iterator<_ForwardIterator>::value,
void
>::type
-vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
+vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n)
{
allocator_type& __a = this->__alloc();
- for (; __first != __last; ++__first)
- {
- __RAII_IncreaseAnnotator __annotator(*this);
- __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
- __annotator.__done();
- ++this->__end_;
- }
+ __RAII_IncreaseAnnotator __annotator(*this, __n);
+ __alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_);
+ __annotator.__done();
}
// Default constructs __n objects starting at __end_
@@ -1177,7 +1165,7 @@
if (__n > 0)
{
allocate(__n);
- __construct_at_end(__first, __last);
+ __construct_at_end(__first, __last, __n);
}
}
@@ -1197,7 +1185,7 @@
if (__n > 0)
{
allocate(__n);
- __construct_at_end(__first, __last);
+ __construct_at_end(__first, __last, __n);
}
}
@@ -1212,7 +1200,7 @@
if (__n > 0)
{
allocate(__n);
- __construct_at_end(__x.__begin_, __x.__end_);
+ __construct_at_end(__x.__begin_, __x.__end_, __n);
}
}
@@ -1227,7 +1215,7 @@
if (__n > 0)
{
allocate(__n);
- __construct_at_end(__x.__begin_, __x.__end_);
+ __construct_at_end(__x.__begin_, __x.__end_, __n);
}
}
@@ -1236,7 +1224,11 @@
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<_Tp, _Allocator>::vector(vector&& __x)
+#if _LIBCPP_STD_VER > 14
+ _NOEXCEPT
+#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+#endif
: __base(_VSTD::move(__x.__alloc()))
{
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1286,7 +1278,7 @@
if (__il.size() > 0)
{
allocate(__il.size());
- __construct_at_end(__il.begin(), __il.end());
+ __construct_at_end(__il.begin(), __il.end(), __il.size());
}
}
@@ -1301,7 +1293,7 @@
if (__il.size() > 0)
{
allocate(__il.size());
- __construct_at_end(__il.begin(), __il.end());
+ __construct_at_end(__il.begin(), __il.end(), __il.size());
}
}
@@ -1394,12 +1386,12 @@
>::type
vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
{
- typename iterator_traits<_ForwardIterator>::difference_type __new_size = _VSTD::distance(__first, __last);
- if (static_cast<size_type>(__new_size) <= capacity())
+ size_type __new_size = static_cast<size_type>(_VSTD::distance(__first, __last));
+ if (__new_size <= capacity())
{
_ForwardIterator __mid = __last;
bool __growing = false;
- if (static_cast<size_type>(__new_size) > size())
+ if (__new_size > size())
{
__growing = true;
__mid = __first;
@@ -1407,15 +1399,15 @@
}
pointer __m = _VSTD::copy(__first, __mid, this->__begin_);
if (__growing)
- __construct_at_end(__mid, __last);
+ __construct_at_end(__mid, __last, __new_size - size());
else
this->__destruct_at_end(__m);
}
else
{
deallocate();
- allocate(__recommend(static_cast<size_type>(__new_size)));
- __construct_at_end(__first, __last);
+ allocate(__recommend(__new_size));
+ __construct_at_end(__first, __last, __new_size);
}
}
@@ -1905,9 +1897,11 @@
pointer __old_last = this->__end_;
for (; this->__end_ != this->__end_cap() && __first != __last; ++__first)
{
+ __RAII_IncreaseAnnotator __annotator(*this);
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
*__first);
++this->__end_;
+ __annotator.__done();
}
__split_buffer<value_type, allocator_type&> __v(__a);
if (__first != __last)
@@ -1967,8 +1961,9 @@
if (__n > __dx)
{
__m = __first;
- _VSTD::advance(__m, this->__end_ - __p);
- __construct_at_end(__m, __last);
+ difference_type __diff = this->__end_ - __p;
+ _VSTD::advance(__m, __diff);
+ __construct_at_end(__m, __last, __n - __diff);
__n = __dx;
}
if (__n > 0)
@@ -2015,8 +2010,12 @@
template <class _Tp, class _Allocator>
void
vector<_Tp, _Allocator>::swap(vector& __x)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
_LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
this->__alloc() == __x.__alloc(),
@@ -2025,7 +2024,8 @@
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__end_, __x.__end_);
_VSTD::swap(this->__end_cap(), __x.__end_cap());
- __base::__swap_alloc(this->__alloc(), __x.__alloc());
+ __swap_allocator(this->__alloc(), __x.__alloc(),
+ integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->swap(this, &__x);
#endif // _LIBCPP_DEBUG_LEVEL >= 2
@@ -2128,13 +2128,7 @@
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
private:
- typedef typename __alloc_traits::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- rebind_alloc<__storage_type>
-#else
- rebind_alloc<__storage_type>::other
-#endif
- __storage_allocator;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __storage_type>::type __storage_allocator;
typedef allocator_traits<__storage_allocator> __storage_traits;
typedef typename __storage_traits::pointer __storage_pointer;
typedef typename __storage_traits::const_pointer __const_storage_pointer;
@@ -2170,9 +2164,14 @@
public:
_LIBCPP_INLINE_VISIBILITY
- vector()
- _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
- _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a);
+ vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
+
+ _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
+#if _LIBCPP_STD_VER <= 14
+ _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value);
+#else
+ _NOEXCEPT;
+#endif
~vector();
explicit vector(size_type __n);
#if _LIBCPP_STD_VER > 11
@@ -2206,7 +2205,11 @@
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
vector(vector&& __v)
+#if _LIBCPP_STD_VER > 14
+ _NOEXCEPT;
+#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+#endif
vector(vector&& __v, const allocator_type& __a);
_LIBCPP_INLINE_VISIBILITY
vector& operator=(vector&& __v)
@@ -2354,8 +2357,12 @@
void clear() _NOEXCEPT {__size_ = 0;}
void swap(vector&)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value);
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT;
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value);
+#endif
void resize(size_type __sz, value_type __x = false);
void flip() _NOEXCEPT;
@@ -2433,26 +2440,6 @@
_NOEXCEPT
{}
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y)
- _NOEXCEPT_(
- !__storage_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
- {__swap_alloc(__x, __y, integral_constant<bool,
- __storage_traits::propagate_on_container_swap::value>());}
-
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__storage_allocator& __x, __storage_allocator& __y, true_type)
- _NOEXCEPT_(__is_nothrow_swappable<allocator_type>::value)
- {
- using _VSTD::swap;
- swap(__x, __y);
- }
- _LIBCPP_INLINE_VISIBILITY
- static void __swap_alloc(__storage_allocator&, __storage_allocator&, false_type)
- _NOEXCEPT
- {}
-
size_t __hash_code() const _NOEXCEPT;
friend class __bit_reference<vector>;
@@ -2559,7 +2546,7 @@
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<bool, _Allocator>::vector()
- _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
+ _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
: __begin_(nullptr),
__size_(0),
__cap_alloc_(0)
@@ -2569,6 +2556,11 @@
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<bool, _Allocator>::vector(const allocator_type& __a)
+#if _LIBCPP_STD_VER <= 14
+ _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
+#else
+ _NOEXCEPT
+#endif
: __begin_(nullptr),
__size_(0),
__cap_alloc_(0, static_cast<__storage_allocator>(__a))
@@ -2807,7 +2799,11 @@
template <class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
vector<bool, _Allocator>::vector(vector&& __v)
+#if _LIBCPP_STD_VER > 14
+ _NOEXCEPT
+#else
_NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+#endif
: __begin_(__v.__begin_),
__size_(__v.__size_),
__cap_alloc_(__v.__cap_alloc_)
@@ -3150,13 +3146,18 @@
template <class _Allocator>
void
vector<bool, _Allocator>::swap(vector& __x)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
- __is_nothrow_swappable<allocator_type>::value)
+#if _LIBCPP_STD_VER >= 14
+ _NOEXCEPT
+#else
+ _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
+ __is_nothrow_swappable<allocator_type>::value)
+#endif
{
_VSTD::swap(this->__begin_, __x.__begin_);
_VSTD::swap(this->__size_, __x.__size_);
_VSTD::swap(this->__cap(), __x.__cap());
- __swap_alloc(this->__alloc(), __x.__alloc());
+ __swap_allocator(this->__alloc(), __x.__alloc(),
+ integral_constant<bool, __alloc_traits::propagate_on_container_swap::value>());
}
template <class _Allocator>
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index d50b2cc..26dee67 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,3 +1,5 @@
+set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" PARENT_SCOPE)
+
# Get sources
file(GLOB LIBCXX_SOURCES ../src/*.cpp)
if(WIN32)
@@ -23,58 +25,70 @@
endif()
if (LIBCXX_ENABLE_SHARED)
- add_library(cxx SHARED
- ${LIBCXX_SOURCES}
- ${LIBCXX_HEADERS}
- )
+ add_library(cxx SHARED ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
else()
- add_library(cxx STATIC
- ${LIBCXX_SOURCES}
- ${LIBCXX_HEADERS}
- )
-endif()
-
-#if LIBCXX_CXX_ABI_LIBRARY_PATH is defined we want to add it to the search path.
-if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
- target_link_libraries(cxx "-L${LIBCXX_CXX_ABI_LIBRARY_PATH}")
+ add_library(cxx STATIC ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
endif()
if (DEFINED LIBCXX_CXX_ABI_DEPS)
add_dependencies(cxx LIBCXX_CXX_ABI_DEPS)
endif()
-set(libraries "")
-if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
- # TODO(ericwf): Remove these GNU specific linker flags and let CMake do the
- # configuration. This will be more portable.
- list(APPEND libraries "-Wl,--whole-archive" "-Wl,-Bstatic")
- list(APPEND libraries "${LIBCXX_CXX_ABI_LIBRARY}")
- list(APPEND libraries "-Wl,-Bdynamic" "-Wl,--no-whole-archive")
-else()
- list(APPEND libraries "${LIBCXX_CXX_ABI_LIBRARY}")
+#if LIBCXX_CXX_ABI_LIBRARY_PATH is defined we want to add it to the search path.
+add_link_flags_if(LIBCXX_CXX_ABI_LIBRARY_PATH "-L${LIBCXX_CXX_ABI_LIBRARY_PATH}")
+
+add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}")
+
+add_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "-Wl,--whole-archive" "-Wl,-Bstatic")
+add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}")
+add_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "-Wl,-Bdynamic" "-Wl,--no-whole-archive")
+
+if (APPLE AND LLVM_USE_SANITIZER)
+ if ("${LLVM_USE_SANITIZER}" STREQUAL "Address")
+ set(LIBFILE "libclang_rt.asan_osx_dynamic.dylib")
+ elseif("${LLVM_USE_SANITIZER}" STREQUAL "Undefined")
+ set(LIBFILE "libclang_rt.ubsan_osx_dynamic.dylib")
+ else()
+ message(WARNING "LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X")
+ endif()
+ if (LIBFILE)
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=lib OUTPUT_VARIABLE LIBDIR RESULT_VARIABLE Result)
+ if (NOT ${Result} EQUAL "0")
+ message(FATAL "Failed to find library resource directory")
+ endif()
+ string(STRIP "${LIBDIR}" LIBDIR)
+ set(LIBDIR "${LIBDIR}/darwin/")
+ if (NOT IS_DIRECTORY "${LIBDIR}")
+ message(FATAL_ERROR "Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER")
+ endif()
+ set(LIBCXX_SANITIZER_LIBRARY "${LIBDIR}/${LIBFILE}")
+ set(LIBCXX_SANITIZER_LIBRARY "${LIBCXX_SANITIZER_LIBRARY}" PARENT_SCOPE)
+ message(STATUS "Manually linking compiler-rt library: ${LIBCXX_SANITIZER_LIBRARY}")
+ add_library_flags("${LIBCXX_SANITIZER_LIBRARY}")
+ add_link_flags("-Wl,-rpath,${LIBDIR}")
+ endif()
endif()
# Generate library list.
-append_if(libraries LIBCXX_HAS_PTHREAD_LIB pthread)
-append_if(libraries LIBCXX_HAS_C_LIB c)
-append_if(libraries LIBCXX_HAS_M_LIB m)
-append_if(libraries LIBCXX_HAS_RT_LIB rt)
-append_if(libraries LIBCXX_HAS_GCC_S_LIB gcc_s)
-
-target_link_libraries(cxx ${libraries})
+add_library_flags_if(LIBCXX_HAS_PTHREAD_LIB pthread)
+add_library_flags_if(LIBCXX_HAS_C_LIB c)
+add_library_flags_if(LIBCXX_HAS_M_LIB m)
+add_library_flags_if(LIBCXX_HAS_RT_LIB rt)
+add_library_flags_if(LIBCXX_HAS_GCC_S_LIB gcc_s)
# Setup flags.
-append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_FPIC_FLAG -fPIC)
-append_if(LIBCXX_LINK_FLAGS LIBCXX_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
+add_flags_if_supported(-fPIC)
+add_link_flags_if_supported(-nodefaultlibs)
-if ( APPLE )
+if ( APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL "libcxxabi" OR
+ LIBCXX_CXX_ABI_LIBNAME STREQUAL "none"))
if (NOT DEFINED LIBCXX_LIBCPPABI_VERSION)
set(LIBCXX_LIBCPPABI_VERSION "2")
endif()
if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" )
- list(APPEND LIBCXX_COMPILE_FLAGS "-U__STRICT_ANSI__")
- list(APPEND LIBCXX_LINK_FLAGS
+ add_definitions(-D__STRICT_ANSI__)
+ add_link_flags(
"-compatibility_version 1"
"-current_version 1"
"-install_name /usr/lib/libc++.1.dylib"
@@ -96,7 +110,7 @@
set (OSX_RE_EXPORT_LINE "/usr/lib/libc++abi.dylib -Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++abi${LIBCXX_LIBCPPABI_VERSION}.exp")
endif()
- list(APPEND LIBCXX_LINK_FLAGS
+ add_link_flags(
"-compatibility_version 1"
"-install_name /usr/lib/libc++.1.dylib"
"-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
@@ -106,8 +120,9 @@
endif()
endif()
-string(REPLACE ";" " " LIBCXX_COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}")
-string(REPLACE ";" " " LIBCXX_LINK_FLAGS "${LIBCXX_LINK_FLAGS}")
+target_link_libraries(cxx ${LIBCXX_LIBRARIES})
+split_list(LIBCXX_COMPILE_FLAGS)
+split_list(LIBCXX_LINK_FLAGS)
set_target_properties(cxx
PROPERTIES
diff --git a/src/algorithm.cpp b/src/algorithm.cpp
index c13d5f2..e548856 100644
--- a/src/algorithm.cpp
+++ b/src/algorithm.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
#include "algorithm"
#include "random"
#include "mutex"
diff --git a/src/any.cpp b/src/any.cpp
new file mode 100644
index 0000000..8c3e977
--- /dev/null
+++ b/src/any.cpp
@@ -0,0 +1,22 @@
+//===---------------------------- any.cpp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "experimental/any"
+
+_LIBCPP_BEGIN_NAMESPACE_LFTS
+
+// TODO(EricWF) Enable or delete these
+//bad_any_cast::bad_any_cast() _NOEXCEPT {}
+//bad_any_cast::~bad_any_cast() _NOEXCEPT {}
+
+const char* bad_any_cast::what() const _NOEXCEPT {
+ return "bad any cast";
+}
+
+_LIBCPP_END_NAMESPACE_LFTS
diff --git a/src/chrono.cpp b/src/chrono.cpp
index 4569411..62149fb 100644
--- a/src/chrono.cpp
+++ b/src/chrono.cpp
@@ -8,14 +8,21 @@
//===----------------------------------------------------------------------===//
#include "chrono"
-#include <sys/time.h> //for gettimeofday and timeval
-#ifdef __APPLE__
+#include "cerrno" // errno
+#include "system_error" // __throw_system_error
+#include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
+
+#if !defined(CLOCK_REALTIME)
+#include <sys/time.h> // for gettimeofday and timeval
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC)
+#if __APPLE__
#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
-#else /* !__APPLE__ */
-#include <cerrno> // errno
-#include <system_error> // __throw_system_error
-#include <time.h> // clock_gettime, CLOCK_MONOTONIC
-#endif // __APPLE__
+#else
+#error "Monotonic clock not implemented"
+#endif
+#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -29,9 +36,16 @@
system_clock::time_point
system_clock::now() _NOEXCEPT
{
+#ifdef CLOCK_REALTIME
+ struct timespec tp;
+ if (0 != clock_gettime(CLOCK_REALTIME, &tp))
+ __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
+ return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
+#else // !CLOCK_REALTIME
timeval tv;
gettimeofday(&tv, 0);
return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
+#endif // CLOCK_REALTIME
}
time_t
@@ -48,10 +62,26 @@
#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
// steady_clock
+//
+// Warning: If this is not truly steady, then it is non-conforming. It is
+// better for it to not exist and have the rest of libc++ use system_clock
+// instead.
const bool steady_clock::is_steady;
-#ifdef __APPLE__
+#ifdef CLOCK_MONOTONIC
+
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
+ struct timespec tp;
+ if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
+ __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
+ return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+}
+
+#elif defined(__APPLE__)
+
// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
// are run time constants supplied by the OS. This clock has no relationship
@@ -108,23 +138,9 @@
return time_point(duration(fp()));
}
-#else // __APPLE__
-// FIXME: if _LIBCPP_HAS_NO_MONOTONIC_CLOCK, then clock_gettime isn't going to
-// work. It may be possible to fall back on something else, depending on the system.
-
-// Warning: If this is not truly steady, then it is non-conforming. It is
-// better for it to not exist and have the rest of libc++ use system_clock
-// instead.
-
-steady_clock::time_point
-steady_clock::now() _NOEXCEPT
-{
- struct timespec tp;
- if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
- __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
- return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
-}
-#endif // __APPLE__
+#else
+#error "Monotonic clock not implemented"
+#endif
#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK
diff --git a/src/debug.cpp b/src/debug.cpp
index 60694a3..b1a16e6 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -214,10 +214,10 @@
else
q->__next_ = p->__next_;
__c_node* c = p->__c_;
- free(p);
--__isz_;
if (c != nullptr)
c->__remove(p);
+ free(p);
}
}
}
diff --git a/src/exception.cpp b/src/exception.cpp
index b5c46c0..2c16060 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -29,7 +29,7 @@
#define __terminate_handler __cxxabiapple::__cxa_terminate_handler
#define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
#endif // _LIBCPPABI_VERSION
-#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
+#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || __has_include(<cxxabi.h>)
#include <cxxabi.h>
using namespace __cxxabiv1;
#if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
@@ -90,14 +90,14 @@
#endif // _LIBCPP_NO_EXCEPTIONS
(*get_terminate())();
// handler should not return
- printf("terminate_handler unexpectedly returned\n");
+ fprintf(stderr, "terminate_handler unexpectedly returned\n");
::abort();
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
// handler should not throw exception
- printf("terminate_handler unexpectedly threw an exception\n");
+ fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
::abort();
}
#endif // _LIBCPP_NO_EXCEPTIONS
@@ -106,18 +106,24 @@
#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)
-bool uncaught_exception() _NOEXCEPT
+bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
+
+int uncaught_exceptions() _NOEXCEPT
{
#if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)
- // on Darwin, there is a helper function so __cxa_get_globals is private
- return __cxa_uncaught_exception();
+ // on Darwin, there is a helper function so __cxa_get_globals is private
+# if _LIBCPPABI_VERSION > 1101
+ return __cxa_uncaught_exceptions();
+# else
+ return __cxa_uncaught_exception() ? 1 : 0;
+# endif
#else // __APPLE__
# if defined(_MSC_VER) && ! defined(__clang__)
- _LIBCPP_WARNING("uncaught_exception not yet implemented")
+ _LIBCPP_WARNING("uncaught_exceptions not yet implemented")
# else
# warning uncaught_exception not yet implemented
# endif
- printf("uncaught_exception not yet implemented\n");
+ fprintf(stderr, "uncaught_exceptions not yet implemented\n");
::abort();
#endif // __APPLE__
}
@@ -190,7 +196,7 @@
# else
# warning exception_ptr not yet implemented
# endif
- printf("exception_ptr not yet implemented\n");
+ fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
#endif
}
@@ -209,7 +215,7 @@
# else
# warning exception_ptr not yet implemented
# endif
- printf("exception_ptr not yet implemented\n");
+ fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
#endif
}
@@ -234,7 +240,7 @@
# else
# warning exception_ptr not yet implemented
# endif
- printf("exception_ptr not yet implemented\n");
+ fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
#endif
}
@@ -278,7 +284,7 @@
# else
# warning exception_ptr not yet implemented
# endif
- printf("exception_ptr not yet implemented\n");
+ fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
#endif
}
@@ -300,7 +306,7 @@
# else
# warning exception_ptr not yet implemented
# endif
- printf("exception_ptr not yet implemented\n");
+ fprintf(stderr, "exception_ptr not yet implemented\n");
::abort();
#endif
}
diff --git a/src/future.cpp b/src/future.cpp
index 0c5c2c4..3132b18 100644
--- a/src/future.cpp
+++ b/src/future.cpp
@@ -98,7 +98,6 @@
#endif
__state_ |= __constructed | ready;
__cv_.notify_all();
- __lk.unlock();
}
void
@@ -111,7 +110,6 @@
#endif
__state_ |= __constructed;
__thread_local_data()->__make_ready_at_thread_exit(this);
- __lk.unlock();
}
void
@@ -124,7 +122,6 @@
#endif
__exception_ = __p;
__state_ |= ready;
- __lk.unlock();
__cv_.notify_all();
}
@@ -138,7 +135,6 @@
#endif
__exception_ = __p;
__thread_local_data()->__make_ready_at_thread_exit(this);
- __lk.unlock();
}
void
@@ -146,7 +142,6 @@
{
unique_lock<mutex> __lk(__mut_);
__state_ |= ready;
- __lk.unlock();
__cv_.notify_all();
}
diff --git a/src/iostream.cpp b/src/iostream.cpp
index 7102e43..e073aec 100644
--- a/src/iostream.cpp
+++ b/src/iostream.cpp
@@ -13,55 +13,75 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-static mbstate_t state_types[6] = {};
-
-_ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin [sizeof(__stdinbuf <char>)];
-_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
-_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
-_ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin [sizeof(__stdinbuf <wchar_t>)];
-_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
-_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
-
+#ifndef _LIBCPP_HAS_NO_STDIN
_ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin [sizeof(istream)];
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)];
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)];
-_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)];
+_ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin [sizeof(__stdinbuf <char>)];
+static mbstate_t mb_cin;
_ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin [sizeof(wistream)];
+_ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin [sizeof(__stdinbuf <wchar_t>)];
+static mbstate_t mb_wcin;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)];
+_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];
+static mbstate_t mb_cout;
_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)];
+_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];
+static mbstate_t mb_wcout;
+#endif
+
+_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)];
+_ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];
+static mbstate_t mb_cerr;
_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)];
+_ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];
+static mbstate_t mb_wcerr;
+
+_ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)];
_ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)];
ios_base::Init __start_std_streams;
ios_base::Init::Init()
{
- istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin, state_types+0) );
- ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, state_types+1));
- ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, state_types+2));
+#ifndef _LIBCPP_HAS_NO_STDIN
+ istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin, &mb_cin));
+ wistream* wcin_ptr = ::new(wcin) wistream(::new(__wcin) __stdinbuf <wchar_t>(stdin, &mb_wcin));
+#endif
+#ifndef _LIBCPP_HAS_NO_STDOUT
+ ostream* cout_ptr = ::new(cout) ostream(::new(__cout) __stdoutbuf<char>(stdout, &mb_cout));
+ wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout));
+#endif
+ ostream* cerr_ptr = ::new(cerr) ostream(::new(__cerr) __stdoutbuf<char>(stderr, &mb_cerr));
::new(clog) ostream(cerr_ptr->rdbuf());
- cin_ptr->tie(cout_ptr);
- _VSTD::unitbuf(*cerr_ptr);
- cerr_ptr->tie(cout_ptr);
-
- wistream* wcin_ptr = ::new(wcin) wistream(::new(__wcin) __stdinbuf <wchar_t>(stdin, state_types+3) );
- wostream* wcout_ptr = ::new(wcout) wostream(::new(__wcout) __stdoutbuf<wchar_t>(stdout, state_types+4));
- wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, state_types+5));
+ wostream* wcerr_ptr = ::new(wcerr) wostream(::new(__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr));
::new(wclog) wostream(wcerr_ptr->rdbuf());
+
+#if !defined(_LIBCPP_HAS_NO_STDIN) && !defined(_LIBCPP_HAS_NO_STDOUT)
+ cin_ptr->tie(cout_ptr);
wcin_ptr->tie(wcout_ptr);
+#endif
+ _VSTD::unitbuf(*cerr_ptr);
_VSTD::unitbuf(*wcerr_ptr);
+#ifndef _LIBCPP_HAS_NO_STDOUT
+ cerr_ptr->tie(cout_ptr);
wcerr_ptr->tie(wcout_ptr);
+#endif
}
ios_base::Init::~Init()
{
+#ifndef _LIBCPP_HAS_NO_STDOUT
ostream* cout_ptr = reinterpret_cast<ostream*>(cout);
- ostream* clog_ptr = reinterpret_cast<ostream*>(clog);
- cout_ptr->flush();
- clog_ptr->flush();
-
wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);
- wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);
+ cout_ptr->flush();
wcout_ptr->flush();
+#endif
+
+ ostream* clog_ptr = reinterpret_cast<ostream*>(clog);
+ wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);
+ clog_ptr->flush();
wclog_ptr->flush();
}
diff --git a/src/locale.cpp b/src/locale.cpp
index 39ff351..bdc73e1 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
// On Solaris, we need to define something to make the C99 parts of localeconv
// visible.
#ifdef __sun__
@@ -29,7 +27,7 @@
#include "cwctype"
#include "__sso_allocator"
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-#include <support/win32/locale_win32.h>
+#include "support/win32/locale_win32.h"
#elif !defined(__ANDROID__)
#include <langinfo.h>
#endif
@@ -577,8 +575,10 @@
locale& g = __global();
locale r = g;
g = loc;
+#ifndef __CloudABI__
if (g.name() != "*")
setlocale(LC_ALL, g.name().c_str());
+#endif
return r;
}
@@ -815,7 +815,7 @@
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
#else
- return (isascii(c) && iswlower_l(c, __cloc())) ? c-L'a'+L'A' : c;
+ return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
#endif
}
@@ -829,7 +829,7 @@
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
: *low;
#else
- *low = (isascii(*low) && islower_l(*low, __cloc())) ? (*low-L'a'+L'A') : *low;
+ *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
#endif
return low;
}
@@ -842,7 +842,7 @@
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
#else
- return (isascii(c) && isupper_l(c, __cloc())) ? c-L'A'+'a' : c;
+ return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
#endif
}
@@ -856,7 +856,7 @@
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
: *low;
#else
- *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-L'A'+L'a' : *low;
+ *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
#endif
return low;
}
@@ -925,7 +925,7 @@
return isascii(c) ?
static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
#else
- return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c;
+ return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
#endif
}
@@ -942,7 +942,7 @@
*low = isascii(*low) ?
static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
#else
- *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low;
+ *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
#endif
return low;
}
@@ -959,7 +959,7 @@
return isascii(c) ?
static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
#else
- return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c;
+ return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
#endif
}
@@ -974,7 +974,7 @@
#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
*low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
#else
- *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low;
+ *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
#endif
return low;
}
@@ -1107,7 +1107,7 @@
#elif defined(__NetBSD__)
return _C_ctype_tab_ + 1;
#elif defined(__GLIBC__)
- return __cloc()->__ctype_b;
+ return _LIBCPP_GET_C_LOCALE->__ctype_b;
#elif __sun__
return __ctype_mask;
#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
@@ -1136,13 +1136,13 @@
const int*
ctype<char>::__classic_lower_table() _NOEXCEPT
{
- return __cloc()->__ctype_tolower;
+ return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
}
const int*
ctype<char>::__classic_upper_table() _NOEXCEPT
{
- return __cloc()->__ctype_toupper;
+ return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
}
#elif __NetBSD__
const short*
@@ -1265,16 +1265,16 @@
#else
bool result = false;
wint_t ch = static_cast<wint_t>(c);
- if (m & space) result |= (iswspace_l(ch, __l) != 0);
- if (m & print) result |= (iswprint_l(ch, __l) != 0);
- if (m & cntrl) result |= (iswcntrl_l(ch, __l) != 0);
- if (m & upper) result |= (iswupper_l(ch, __l) != 0);
- if (m & lower) result |= (iswlower_l(ch, __l) != 0);
- if (m & alpha) result |= (iswalpha_l(ch, __l) != 0);
- if (m & digit) result |= (iswdigit_l(ch, __l) != 0);
- if (m & punct) result |= (iswpunct_l(ch, __l) != 0);
- if (m & xdigit) result |= (iswxdigit_l(ch, __l) != 0);
- if (m & blank) result |= (iswblank_l(ch, __l) != 0);
+ if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
+ if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
+ if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
+ if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
+ if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
+ if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
+ if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
+ if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
+ if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
+ if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
return result;
#endif
}
@@ -1292,22 +1292,32 @@
wint_t ch = static_cast<wint_t>(*low);
if (iswspace_l(ch, __l))
*vec |= space;
+#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
if (iswprint_l(ch, __l))
*vec |= print;
+#endif
if (iswcntrl_l(ch, __l))
*vec |= cntrl;
if (iswupper_l(ch, __l))
*vec |= upper;
if (iswlower_l(ch, __l))
*vec |= lower;
+#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
if (iswalpha_l(ch, __l))
*vec |= alpha;
+#endif
if (iswdigit_l(ch, __l))
*vec |= digit;
if (iswpunct_l(ch, __l))
*vec |= punct;
+#ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
if (iswxdigit_l(ch, __l))
*vec |= xdigit;
+#endif
+#if !defined(__sun__)
+ if (iswblank_l(ch, __l))
+ *vec |= blank;
+#endif
}
}
return low;
@@ -1323,16 +1333,16 @@
break;
#else
wint_t ch = static_cast<wint_t>(*low);
- if (m & space && iswspace_l(ch, __l)) break;
- if (m & print && iswprint_l(ch, __l)) break;
- if (m & cntrl && iswcntrl_l(ch, __l)) break;
- if (m & upper && iswupper_l(ch, __l)) break;
- if (m & lower && iswlower_l(ch, __l)) break;
- if (m & alpha && iswalpha_l(ch, __l)) break;
- if (m & digit && iswdigit_l(ch, __l)) break;
- if (m & punct && iswpunct_l(ch, __l)) break;
- if (m & xdigit && iswxdigit_l(ch, __l)) break;
- if (m & blank && iswblank_l(ch, __l)) break;
+ if ((m & space) == space && iswspace_l(ch, __l)) break;
+ if ((m & print) == print && iswprint_l(ch, __l)) break;
+ if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
+ if ((m & upper) == upper && iswupper_l(ch, __l)) break;
+ if ((m & lower) == lower && iswlower_l(ch, __l)) break;
+ if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
+ if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
+ if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
+ if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
+ if ((m & blank) == blank && iswblank_l(ch, __l)) break;
#endif
}
return low;
@@ -1348,16 +1358,16 @@
break;
#else
wint_t ch = static_cast<wint_t>(*low);
- if (m & space && iswspace_l(ch, __l)) continue;
- if (m & print && iswprint_l(ch, __l)) continue;
- if (m & cntrl && iswcntrl_l(ch, __l)) continue;
- if (m & upper && iswupper_l(ch, __l)) continue;
- if (m & lower && iswlower_l(ch, __l)) continue;
- if (m & alpha && iswalpha_l(ch, __l)) continue;
- if (m & digit && iswdigit_l(ch, __l)) continue;
- if (m & punct && iswpunct_l(ch, __l)) continue;
- if (m & xdigit && iswxdigit_l(ch, __l)) continue;
- if (m & blank && iswblank_l(ch, __l)) continue;
+ if ((m & space) == space && iswspace_l(ch, __l)) continue;
+ if ((m & print) == print && iswprint_l(ch, __l)) continue;
+ if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
+ if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
+ if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
+ if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
+ if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
+ if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
+ if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
+ if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
break;
#endif
}
@@ -1649,7 +1659,7 @@
frm_nxt = frm;
return frm_nxt == frm_end ? ok : partial;
}
- if (n == 0)
+ if (n == size_t(-1))
return error;
to_nxt += n;
if (to_nxt == to_end)
@@ -1699,22 +1709,23 @@
int
codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
{
+#ifndef __CloudABI__
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
- if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0)
+ if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
#else
- if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) == 0)
+ if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
#endif
- {
- // stateless encoding
+ return -1;
+#endif
+
+ // stateless encoding
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
- if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
+ if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings
#else
- if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
+ if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings
#endif
- return 1; // which take more than 1 char to form a wchar_t
- return 0;
- }
- return -1;
+ return 1; // which take more than 1 char to form a wchar_t
+ return 0;
}
bool
diff --git a/src/memory.cpp b/src/memory.cpp
index 8a4eb34..66fb143 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -13,24 +13,28 @@
#include "mutex"
#include "thread"
#endif
+#include "support/atomic_support.h"
_LIBCPP_BEGIN_NAMESPACE_STD
namespace
{
+// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
+// should be sufficient for thread safety.
+// See https://llvm.org/bugs/show_bug.cgi?id=22803
template <class T>
inline T
increment(T& t) _NOEXCEPT
{
- return __sync_add_and_fetch(&t, 1);
+ return __libcpp_atomic_add(&t, 1, _AO_Relaxed);
}
template <class T>
inline T
decrement(T& t) _NOEXCEPT
{
- return __sync_add_and_fetch(&t, -1);
+ return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel);
}
} // namespace
@@ -99,14 +103,13 @@
__shared_weak_count*
__shared_weak_count::lock() _NOEXCEPT
{
- long object_owners = __shared_owners_;
+ long object_owners = __libcpp_atomic_load(&__shared_owners_);
while (object_owners != -1)
{
- if (__sync_bool_compare_and_swap(&__shared_owners_,
- object_owners,
- object_owners+1))
+ if (__libcpp_atomic_compare_exchange(&__shared_owners_,
+ &object_owners,
+ object_owners+1))
return this;
- object_owners = __shared_owners_;
}
return 0;
}
diff --git a/src/mutex.cpp b/src/mutex.cpp
index e56271d..5f8ba0a 100644
--- a/src/mutex.cpp
+++ b/src/mutex.cpp
@@ -12,6 +12,7 @@
#include "limits"
#include "system_error"
#include "cassert"
+#include "support/atomic_support.h"
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
@@ -220,6 +221,9 @@
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
#endif
+/// NOTE: Changes to flag are done via relaxed atomic stores
+/// even though the accesses are protected by a mutex because threads
+/// just entering 'call_once` concurrently read from flag.
void
__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
{
@@ -252,11 +256,11 @@
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
- flag = 1;
+ __libcpp_relaxed_store(&flag, 1ul);
pthread_mutex_unlock(&mut);
func(arg);
pthread_mutex_lock(&mut);
- flag = ~0ul;
+ __libcpp_relaxed_store(&flag, ~0ul);
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cv);
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -264,7 +268,7 @@
catch (...)
{
pthread_mutex_lock(&mut);
- flag = 0ul;
+ __libcpp_relaxed_store(&flag, 0ul);
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cv);
throw;
diff --git a/src/new.cpp b/src/new.cpp
index c46d073..c28fcb5 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -140,13 +140,6 @@
_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
void
-operator delete(void* ptr, size_t, const std::nothrow_t& nt) _NOEXCEPT
-{
- ::operator delete(ptr, nt);
-}
-
-_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
-void
operator delete[] (void* ptr) _NOEXCEPT
{
::operator delete(ptr);
@@ -166,13 +159,6 @@
::operator delete[](ptr);
}
-_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
-void
-operator delete[] (void* ptr, size_t, const std::nothrow_t& nt) _NOEXCEPT
-{
- ::operator delete[](ptr, nt);
-}
-
#endif // !__GLIBCXX__
namespace std
diff --git a/src/random.cpp b/src/random.cpp
index 0a1d2a5..4ab424e 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -7,11 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_WIN32)
+#if defined(_LIBCPP_USING_WIN32_RANDOM)
// Must be defined before including stdlib.h to enable rand_s().
#define _CRT_RAND_S
-#include <stdio.h>
-#endif // defined(_WIN32)
+#endif // defined(_LIBCPP_USING_WIN32_RANDOM)
#include "random"
#include "system_error"
@@ -19,46 +18,27 @@
#if defined(__sun__)
#define rename solaris_headers_are_broken
#endif // defined(__sun__)
-#if !defined(_WIN32)
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_LIBCPP_USING_DEV_RANDOM)
#include <fcntl.h>
#include <unistd.h>
-#endif // !defined(_WIN32)
-#include <errno.h>
-#if defined(_LIBCPP_USING_NACL_RANDOM)
+#elif defined(_LIBCPP_USING_NACL_RANDOM)
#include <nacl/nacl_random.h>
-#endif // defined(_LIBCPP_USING_NACL_RANDOM)
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
-#if defined(_WIN32)
-
-random_device::random_device(const string&)
-{
-}
-
-random_device::~random_device()
-{
-}
-
-unsigned
-random_device::operator()()
-{
- unsigned r;
- errno_t err = rand_s(&r);
- if (err)
- __throw_system_error(err, "random_device rand_s failed.");
- return r;
-}
-
-#elif defined(_LIBCPP_USING_NACL_RANDOM)
+#if defined(_LIBCPP_USING_ARC4_RANDOM)
random_device::random_device(const string& __token)
{
if (__token != "/dev/urandom")
__throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
- int error = nacl_secure_random_init();
- if (error)
- __throw_system_error(error, ("random device failed to open " + __token).c_str());
}
random_device::~random_device()
@@ -68,18 +48,10 @@
unsigned
random_device::operator()()
{
- unsigned r;
- size_t n = sizeof(r);
- size_t bytes_written;
- int error = nacl_secure_random(&r, n, &bytes_written);
- if (error != 0)
- __throw_system_error(error, "random_device failed getting bytes");
- else if (bytes_written != n)
- __throw_runtime_error("random_device failed to obtain enough bytes");
- return r;
+ return arc4random();
}
-#else // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM)
+#elif defined(_LIBCPP_USING_DEV_RANDOM)
random_device::random_device(const string& __token)
: __f_(open(__token.c_str(), O_RDONLY))
@@ -116,7 +88,60 @@
return r;
}
-#endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM)
+#elif defined(_LIBCPP_USING_NACL_RANDOM)
+
+random_device::random_device(const string& __token)
+{
+ if (__token != "/dev/urandom")
+ __throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
+ int error = nacl_secure_random_init();
+ if (error)
+ __throw_system_error(error, ("random device failed to open " + __token).c_str());
+}
+
+random_device::~random_device()
+{
+}
+
+unsigned
+random_device::operator()()
+{
+ unsigned r;
+ size_t n = sizeof(r);
+ size_t bytes_written;
+ int error = nacl_secure_random(&r, n, &bytes_written);
+ if (error != 0)
+ __throw_system_error(error, "random_device failed getting bytes");
+ else if (bytes_written != n)
+ __throw_runtime_error("random_device failed to obtain enough bytes");
+ return r;
+}
+
+#elif defined(_LIBCPP_USING_WIN32_RANDOM)
+
+random_device::random_device(const string& __token)
+{
+ if (__token != "/dev/urandom")
+ __throw_system_error(ENOENT, ("random device not supported " + __token).c_str());
+}
+
+random_device::~random_device()
+{
+}
+
+unsigned
+random_device::operator()()
+{
+ unsigned r;
+ errno_t err = rand_s(&r);
+ if (err)
+ __throw_system_error(err, "random_device rand_s failed.");
+ return r;
+}
+
+#else
+#error "Random device not implemented for this architecture"
+#endif
double
random_device::entropy() const _NOEXCEPT
diff --git a/src/shared_mutex.cpp b/src/shared_mutex.cpp
index 2b78c1f..874aceb 100644
--- a/src/shared_mutex.cpp
+++ b/src/shared_mutex.cpp
@@ -15,7 +15,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-shared_timed_mutex::shared_timed_mutex()
+// Shared Mutex Base
+__shared_mutex_base::__shared_mutex_base()
: __state_(0)
{
}
@@ -23,7 +24,7 @@
// Exclusive ownership
void
-shared_timed_mutex::lock()
+__shared_mutex_base::lock()
{
unique_lock<mutex> lk(__mut_);
while (__state_ & __write_entered_)
@@ -34,7 +35,7 @@
}
bool
-shared_timed_mutex::try_lock()
+__shared_mutex_base::try_lock()
{
unique_lock<mutex> lk(__mut_);
if (__state_ == 0)
@@ -46,7 +47,7 @@
}
void
-shared_timed_mutex::unlock()
+__shared_mutex_base::unlock()
{
lock_guard<mutex> _(__mut_);
__state_ = 0;
@@ -56,7 +57,7 @@
// Shared ownership
void
-shared_timed_mutex::lock_shared()
+__shared_mutex_base::lock_shared()
{
unique_lock<mutex> lk(__mut_);
while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
@@ -67,7 +68,7 @@
}
bool
-shared_timed_mutex::try_lock_shared()
+__shared_mutex_base::try_lock_shared()
{
unique_lock<mutex> lk(__mut_);
unsigned num_readers = __state_ & __n_readers_;
@@ -82,7 +83,7 @@
}
void
-shared_timed_mutex::unlock_shared()
+__shared_mutex_base::unlock_shared()
{
lock_guard<mutex> _(__mut_);
unsigned num_readers = (__state_ & __n_readers_) - 1;
@@ -101,6 +102,16 @@
}
+// Shared Timed Mutex
+// These routines are here for ABI stability
+shared_timed_mutex::shared_timed_mutex() : __base() {}
+void shared_timed_mutex::lock() { return __base.lock(); }
+bool shared_timed_mutex::try_lock() { return __base.try_lock(); }
+void shared_timed_mutex::unlock() { return __base.unlock(); }
+void shared_timed_mutex::lock_shared() { return __base.lock_shared(); }
+bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }
+void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }
+
_LIBCPP_END_NAMESPACE_STD
#endif // !_LIBCPP_HAS_NO_THREADS
diff --git a/src/string.cpp b/src/string.cpp
index 8aea0f7..d3f29df 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
#include "string"
#include "cstdlib"
#include "cwchar"
@@ -41,7 +39,7 @@
#ifndef _LIBCPP_NO_EXCEPTIONS
throw T( msg );
#else
- printf("%s\n", msg.c_str());
+ fprintf(stderr, "%s\n", msg.c_str());
abort();
#endif
}
diff --git a/src/support/atomic_support.h b/src/support/atomic_support.h
new file mode 100644
index 0000000..e738a51
--- /dev/null
+++ b/src/support/atomic_support.h
@@ -0,0 +1,142 @@
+#ifndef ATOMIC_SUPPORT_H
+#define ATOMIC_SUPPORT_H
+
+#include "__config"
+#include "memory" // for __libcpp_relaxed_load
+
+#if defined(__clang__) && __has_builtin(__atomic_load_n) \
+ && __has_builtin(__atomic_store_n) \
+ && __has_builtin(__atomic_add_fetch) \
+ && __has_builtin(__atomic_compare_exchange_n) \
+ && defined(__ATOMIC_RELAXED) \
+ && defined(__ATOMIC_CONSUME) \
+ && defined(__ATOMIC_ACQUIRE) \
+ && defined(__ATOMIC_RELEASE) \
+ && defined(__ATOMIC_ACQ_REL) \
+ && defined(__ATOMIC_SEQ_CST)
+# define _LIBCPP_HAS_ATOMIC_BUILTINS
+#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
+# define _LIBCPP_HAS_ATOMIC_BUILTINS
+#endif
+
+#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)
+# if defined(_MSC_VER) && !defined(__clang__)
+ _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported")
+# else
+# warning Building libc++ without __atomic builtins is unsupported
+# endif
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace {
+
+#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)
+
+enum __libcpp_atomic_order {
+ _AO_Relaxed = __ATOMIC_RELAXED,
+ _AO_Consume = __ATOMIC_CONSUME,
+ _AO_Aquire = __ATOMIC_ACQUIRE,
+ _AO_Release = __ATOMIC_RELEASE,
+ _AO_Acq_Rel = __ATOMIC_ACQ_REL,
+ _AO_Seq = __ATOMIC_SEQ_CST
+};
+
+template <class _ValueType, class _FromType>
+inline _LIBCPP_INLINE_VISIBILITY
+void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
+ int __order = _AO_Seq)
+{
+ __atomic_store_n(__dest, __val, __order);
+}
+
+template <class _ValueType, class _FromType>
+inline _LIBCPP_INLINE_VISIBILITY
+void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
+{
+ __atomic_store_n(__dest, __val, _AO_Relaxed);
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_atomic_load(_ValueType const* __val,
+ int __order = _AO_Seq)
+{
+ return __atomic_load_n(__val, __order);
+}
+
+template <class _ValueType, class _AddType>
+inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
+ int __order = _AO_Seq)
+{
+ return __atomic_add_fetch(__val, __a, __order);
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+bool __libcpp_atomic_compare_exchange(_ValueType* __val,
+ _ValueType* __expected, _ValueType __after,
+ int __success_order = _AO_Seq,
+ int __fail_order = _AO_Seq)
+{
+ return __atomic_compare_exchange_n(__val, __expected, __after, true,
+ __success_order, __fail_order);
+}
+
+#else // _LIBCPP_HAS_NO_THREADS
+
+enum __libcpp_atomic_order {
+ _AO_Relaxed,
+ _AO_Consume,
+ _AO_Acquire,
+ _AO_Release,
+ _AO_Acq_Rel,
+ _AO_Seq
+};
+
+template <class _ValueType, class _FromType>
+inline _LIBCPP_INLINE_VISIBILITY
+void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
+ int = 0)
+{
+ *__dest = __val;
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_atomic_load(_ValueType const* __val,
+ int = 0)
+{
+ return *__val;
+}
+
+template <class _ValueType, class _AddType>
+inline _LIBCPP_INLINE_VISIBILITY
+_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
+ int = 0)
+{
+ return *__val += __a;
+}
+
+template <class _ValueType>
+inline _LIBCPP_INLINE_VISIBILITY
+bool __libcpp_atomic_compare_exchange(_ValueType* __val,
+ _ValueType* __expected, _ValueType __after,
+ int = 0, int = 0)
+{
+ if (*__val == *__expected) {
+ *__val = __after;
+ return true;
+ }
+ *__expected = *__val;
+ return false;
+}
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+} // end namespace
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // ATOMIC_SUPPORT_H
diff --git a/src/system_error.cpp b/src/system_error.cpp
index c032fc0..18f668f 100644
--- a/src/system_error.cpp
+++ b/src/system_error.cpp
@@ -152,7 +152,7 @@
what_arg += ": ";
what_arg += ec.message();
}
- return _VSTD::move(what_arg);
+ return what_arg;
}
system_error::system_error(error_code ec, const string& what_arg)
diff --git a/src/thread.cpp b/src/thread.cpp
index 6aad558..bd27f28 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -17,9 +17,9 @@
#include "limits"
#include <sys/types.h>
#if !defined(_WIN32)
-# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__)
+# if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__)
# include <sys/sysctl.h>
-# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__)
+# endif // !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) && !defined(__CloudABI__)
# include <unistd.h>
#endif // !_WIN32
diff --git a/src/valarray.cpp b/src/valarray.cpp
index e4c9ed0..2d8db52 100644
--- a/src/valarray.cpp
+++ b/src/valarray.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
-
#include "valarray"
_LIBCPP_BEGIN_NAMESPACE_STD
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 6af4c98..60dd7c2 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -6,69 +6,48 @@
endif()
endmacro()
-set(LIT_EXECUTABLE "" CACHE FILEPATH "Path to LLVM's llvm-lit.")
+set(LIBCXX_LIT_VARIANT "libcxx" CACHE STRING
+ "Configuration variant to use for LIT.")
-if(LIBCXX_BUILT_STANDALONE)
- # Make sure we can use the console pool for recent cmake and ninja > 1.5
- if(CMAKE_VERSION VERSION_LESS 3.1.20141117)
- set(cmake_3_2_USES_TERMINAL)
- else()
- set(cmake_3_2_USES_TERMINAL USES_TERMINAL)
- endif()
-else()
- include(FindPythonInterp)
- if(PYTHONINTERP_FOUND)
- set(LIT_EXECUTABLE
- ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/utils/lit/lit.py)
- else()
- message(WARNING "Could not find Python, cannot set LIT_EXECUTABLE.")
- endif()
+pythonize_bool(LIBCXX_ENABLE_EXCEPTIONS)
+pythonize_bool(LIBCXX_ENABLE_RTTI)
+pythonize_bool(LIBCXX_ENABLE_SHARED)
+pythonize_bool(LIBCXX_BUILD_32_BITS)
+pythonize_bool(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE)
+pythonize_bool(LIBCXX_ENABLE_STDIN)
+pythonize_bool(LIBCXX_ENABLE_STDOUT)
+pythonize_bool(LIBCXX_ENABLE_THREADS)
+pythonize_bool(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS)
+pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK)
+pythonize_bool(LIBCXX_GENERATE_COVERAGE)
+pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
+
+# The tests shouldn't link to any ABI library when it has been linked into
+# libc++ statically.
+if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
+ set(LIBCXX_CXX_ABI_LIBNAME "none")
endif()
+set(LIBCXX_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
+ "TargetInfo to use when setting up test environment.")
+set(LIBCXX_EXECUTOR "None" CACHE STRING
+ "Executor to use when running tests.")
-if (LIT_EXECUTABLE)
- set(LIT_ARGS_DEFAULT "-sv --show-unsupported --show-xfail")
- if (MSVC OR XCODE)
- set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
- endif()
- set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}"
- CACHE STRING "Default options for lit")
- set(LIT_ARGS "${LLVM_LIT_ARGS}")
- separate_arguments(LIT_ARGS)
+set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!")
- set(LIBCXX_LIT_VARIANT "libcxx" CACHE STRING
- "Configuration variant to use for LIT.")
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ @ONLY)
- pythonize_bool(LIBCXX_ENABLE_EXCEPTIONS)
- pythonize_bool(LIBCXX_ENABLE_RTTI)
- pythonize_bool(LIBCXX_ENABLE_SHARED)
- pythonize_bool(LIBCXX_BUILD_32_BITS)
- pythonize_bool(LIBCXX_ENABLE_THREADS)
- pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK)
- # The tests shouldn't link to any ABI library when it has been linked into
- # libc++ statically.
- if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY)
- set(LIBCXX_CXX_ABI_LIBNAME "none")
- endif()
- set(LIBCXX_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
- "TargetInfo to use when setting up test environment.")
- set(LIBCXX_EXECUTOR "None" CACHE STRING
- "Executor to use when running tests.")
+add_lit_testsuite(check-libcxx
+ "Running libcxx tests"
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS cxx)
- set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!")
-
- configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
- ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
- @ONLY)
-
- add_custom_target(check-libcxx
- COMMAND ${LIT_EXECUTABLE}
- ${LIT_ARGS}
- ${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS cxx
- COMMENT "Running libcxx tests"
- ${cmake_3_2_USES_TERMINAL})
-else()
- message(WARNING
- "LIT_EXECUTABLE not set, no check-libcxx target will be available!")
+if (LIBCXX_GENERATE_COVERAGE)
+ include(CodeCoverage)
+ set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/coverage")
+ set(capture_dirs "${LIBCXX_LIB_CMAKEFILES_DIR}/cxx.dir/;${CMAKE_CURRENT_BINARY_DIR}")
+ set(extract_dirs "${LIBCXX_SOURCE_DIR}/include;${LIBCXX_SOURCE_DIR}/src")
+ setup_lcov_test_target_coverage("cxx" "${output_dir}" "${capture_dirs}" "${extract_dirs}")
endif()
diff --git a/test/libcxx/compiler.py b/test/libcxx/compiler.py
index 4828874..24ac431 100644
--- a/test/libcxx/compiler.py
+++ b/test/libcxx/compiler.py
@@ -107,12 +107,15 @@
# Otherwise wrap the filename in a context manager function.
with_fn = lambda: libcxx.util.nullContext(object_file)
with with_fn() as object_file:
- cmd, output, err, rc = self.compile(source_file, object_file,
- flags=flags, env=env, cwd=cwd)
+ cc_cmd, cc_stdout, cc_stderr, rc = self.compile(
+ source_file, object_file, flags=flags, env=env, cwd=cwd)
if rc != 0:
- return cmd, output, err, rc
- return self.link(object_file, out=out, flags=flags, env=env,
- cwd=cwd)
+ return cc_cmd, cc_stdout, cc_stderr, rc
+
+ link_cmd, link_stdout, link_stderr, rc = self.link(
+ object_file, out=out, flags=flags, env=env, cwd=cwd)
+ return (cc_cmd + ['&&'] + link_cmd, cc_stdout + link_stdout,
+ cc_stderr + link_stderr, rc)
def dumpMacros(self, source_files=None, flags=[], env=None, cwd=None):
if source_files is None:
@@ -134,3 +137,27 @@
def getTriple(self):
cmd = [self.path] + self.flags + ['-dumpmachine']
return lit.util.capture(cmd).strip()
+
+ def hasCompileFlag(self, flag):
+ if isinstance(flag, list):
+ flags = list(flag)
+ else:
+ flags = [flag]
+ # Add -Werror to ensure that an unrecognized flag causes a non-zero
+ # exit code. -Werror is supported on all known compiler types.
+ if self.type is not None:
+ flags += ['-Werror']
+ cmd, out, err, rc = self.compile(os.devnull, out=os.devnull,
+ flags=flags)
+ return rc == 0
+
+ def addCompileFlagIfSupported(self, flag):
+ if isinstance(flag, list):
+ flags = list(flag)
+ else:
+ flags = [flag]
+ if self.hasCompileFlag(flags):
+ self.compile_flags += flags
+ return True
+ else:
+ return False
diff --git a/test/std/containers/sequences/vector/asan.pass.cpp b/test/libcxx/containers/sequences/vector/asan.pass.cpp
similarity index 75%
rename from test/std/containers/sequences/vector/asan.pass.cpp
rename to test/libcxx/containers/sequences/vector/asan.pass.cpp
index 86c02b2..0a11147 100644
--- a/test/std/containers/sequences/vector/asan.pass.cpp
+++ b/test/libcxx/containers/sequences/vector/asan.pass.cpp
@@ -15,15 +15,18 @@
#include <cassert>
#include <cstdlib>
-#include "min_allocator.h"
#include "asan_testing.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
#ifndef _LIBCPP_HAS_NO_ASAN
extern "C" void __asan_set_error_exit_code(int);
+
int main()
{
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef int T;
typedef std::vector<T, min_allocator<T>> C;
@@ -33,7 +36,18 @@
T foo = c[c.size()]; // bad, but not caught by ASAN
}
#endif
-
+
+ {
+ typedef input_iterator<int*> MyInputIter;
+ // Sould not trigger ASan.
+ std::vector<int> v;
+ v.reserve(1);
+ int i[] = {42};
+ v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
+ assert(v[0] == 42);
+ assert(is_contiguous_container_asan_correct(v));
+ }
+
__asan_set_error_exit_code(0);
{
typedef int T;
@@ -41,7 +55,7 @@
const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
C c(std::begin(t), std::end(t));
c.reserve(2*c.size());
- assert(is_contiguous_container_asan_correct(c));
+ assert(is_contiguous_container_asan_correct(c));
assert(!__sanitizer_verify_contiguous_container ( c.data(), c.data() + 1, c.data() + c.capacity()));
T foo = c[c.size()]; // should trigger ASAN
assert(false); // if we got here, ASAN didn't trigger
diff --git a/test/std/containers/sequences/vector/asan_throw.pass.cc b/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
similarity index 84%
rename from test/std/containers/sequences/vector/asan_throw.pass.cc
rename to test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
index a1dce4a..c100da1 100644
--- a/test/std/containers/sequences/vector/asan_throw.pass.cc
+++ b/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
@@ -37,6 +37,22 @@
char a;
};
+class ThrowOnCopy {
+public:
+ ThrowOnCopy() : should_throw(false) {}
+ explicit ThrowOnCopy(bool should_throw) : should_throw(should_throw) {}
+
+ ThrowOnCopy(ThrowOnCopy const & other)
+ : should_throw(other.should_throw)
+ {
+ if (should_throw) {
+ throw 0;
+ }
+ }
+
+ bool should_throw;
+};
+
void test_push_back() {
std::vector<X> v;
v.reserve(2);
@@ -157,6 +173,23 @@
assert(0);
}
+
+void test_insert_n2() {
+ std::vector<ThrowOnCopy> v(10);
+ v.reserve(100);
+ assert(v.size() == 10);
+ v[6].should_throw = true;
+ try {
+ v.insert(v.cbegin(), 5, ThrowOnCopy());
+ assert(0);
+ } catch (int e) {
+ assert(v.size() == 11);
+ assert(is_contiguous_container_asan_correct(v));
+ return;
+ }
+ assert(0);
+}
+
void test_resize() {
std::vector<X> v;
v.reserve(3);
@@ -193,6 +226,7 @@
test_emplace();
test_insert_range2();
test_insert_n();
+ test_insert_n2();
test_resize();
test_resize_param();
}
diff --git a/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp b/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
new file mode 100644
index 0000000..76ceafe
--- /dev/null
+++ b/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// Check that we don't allocate when trying to insert a duplicate value into a
+// unordered_set. See PR12999 http://llvm.org/bugs/show_bug.cgi?id=12999
+
+#include <cassert>
+#include <unordered_set>
+#include "count_new.hpp"
+#include "MoveOnly.h"
+
+int main()
+{
+ {
+ std::unordered_set<int> s;
+ assert(globalMemCounter.checkNewCalledEq(0));
+
+ for(int i=0; i < 100; ++i)
+ s.insert(3);
+
+ assert(s.size() == 1);
+ assert(s.count(3) == 1);
+ assert(globalMemCounter.checkNewCalledEq(2));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ globalMemCounter.reset();
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ std::unordered_set<MoveOnly> s;
+ assert(globalMemCounter.checkNewCalledEq(0));
+
+ for(int i=0; i<100; i++)
+ s.insert(MoveOnly(3));
+
+ assert(s.size() == 1);
+ assert(s.count(MoveOnly(3)) == 1);
+ assert(globalMemCounter.checkNewCalledEq(2));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ globalMemCounter.reset();
+#endif
+}
diff --git a/test/libcxx/double_include.sh.cpp b/test/libcxx/double_include.sh.cpp
index fd08128..5620e5b 100644
--- a/test/libcxx/double_include.sh.cpp
+++ b/test/libcxx/double_include.sh.cpp
@@ -49,6 +49,7 @@
#include <cwctype>
#include <deque>
#include <exception>
+#include <experimental/algorithm>
#include <experimental/chrono>
#include <experimental/dynarray>
#include <experimental/optional>
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp
similarity index 69%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp
index b58f5c5..accdd69 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/libcxx/experimental/algorithms/header.algorithm.synop/includes.pass.cpp
@@ -7,6 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// <experimental/algorithm>
+
+#include <experimental/algorithm>
+
+#ifndef _LIBCPP_ALGORITHM
+# error "<experimental/algorithm> must include <algorithm>"
+#endif
+
int main()
{
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/libcxx/experimental/algorithms/version.pass.cpp
similarity index 73%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/libcxx/experimental/algorithms/version.pass.cpp
index b58f5c5..6d9d0c6 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/libcxx/experimental/algorithms/version.pass.cpp
@@ -7,6 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// <experimental/algorithm>
+
+#include <experimental/algorithm>
+
+#ifndef _LIBCPP_VERSION
+# error _LIBCPP_VERSION not defined
+#endif
+
int main()
{
}
diff --git a/test/libcxx/experimental/any/size_and_alignment.pass.cpp b/test/libcxx/experimental/any/size_and_alignment.pass.cpp
new file mode 100644
index 0000000..b7db540
--- /dev/null
+++ b/test/libcxx/experimental/any/size_and_alignment.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <experimental/any>
+
+int main()
+{
+ using std::experimental::any;
+ static_assert(sizeof(any) == sizeof(void*)*4, "");
+ static_assert(alignof(any) == alignof(void*), "");
+}
diff --git a/test/libcxx/experimental/any/small_type.pass.cpp b/test/libcxx/experimental/any/small_type.pass.cpp
new file mode 100644
index 0000000..bcd15f1
--- /dev/null
+++ b/test/libcxx/experimental/any/small_type.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <experimental/any>
+#include "any_helpers.h"
+
+class SmallThrowsDtor
+{
+public:
+ SmallThrowsDtor() {}
+ SmallThrowsDtor(SmallThrowsDtor const &) noexcept {}
+ SmallThrowsDtor(SmallThrowsDtor &&) noexcept {}
+ ~SmallThrowsDtor() noexcept(false) {}
+};
+
+int main()
+{
+ using std::experimental::any;
+ using std::experimental::__any_imp::_IsSmallObject;
+ static_assert(_IsSmallObject<small>::value, "");
+ static_assert(_IsSmallObject<void*>::value, "");
+ static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
+ static_assert(!_IsSmallObject<large>::value, "");
+ // long double is over aligned.
+ static_assert(sizeof(long double) <= sizeof(void*) * 3, "");
+ static_assert(alignof(long double) > alignof(void*), "");
+ static_assert(!_IsSmallObject<long double>::value, "");
+}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/libcxx/experimental/any/version.pass.cpp
similarity index 75%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/libcxx/experimental/any/version.pass.cpp
index b58f5c5..611d650 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/libcxx/experimental/any/version.pass.cpp
@@ -7,6 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// <experimental/any>
+
+#include <experimental/any>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
int main()
{
}
diff --git a/test/std/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/alloc.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.cons/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.cons/default.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.data/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.data/default.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.data/default.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.mutate/default.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.overview/at.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/at.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/begin_end.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/capacity.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/front_back.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.overview/indexing.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.traits/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.traits/default.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/dynarray.zero/default.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/dynarray.zero/default.pass.cpp
diff --git a/test/std/containers/sequences/dynarray/nothing_to_do.pass.cpp b/test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp
similarity index 100%
rename from test/std/containers/sequences/dynarray/nothing_to_do.pass.cpp
rename to test/libcxx/experimental/containers/sequences/dynarray/nothing_to_do.pass.cpp
diff --git a/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp
index 2ab3449..db9026a 100644
--- a/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp
+++ b/test/libcxx/experimental/utilities/ratio/header.ratio.synop/includes.pass.cpp
@@ -13,7 +13,7 @@
#include <experimental/ratio>
-#ifndef _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER > 11
# ifndef _LIBCPP_RATIO
# error " <experimental/ratio> must include <ratio>"
# endif
diff --git a/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp b/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp
index 57cbb73..88c7458 100644
--- a/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp
+++ b/test/libcxx/experimental/utilities/syserror/header.system_error.synop/includes.pass.cpp
@@ -11,7 +11,7 @@
#include <experimental/system_error>
-#ifndef _LIBCPP_STD_VER > 11
+#if _LIBCPP_STD_VER > 11
# ifndef _LIBCPP_SYSTEM_ERROR
# error "<experimental/system_error> must include <system_error>"
# endif
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
similarity index 64%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
index b58f5c5..544ddfb 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/libcxx/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
@@ -7,6 +7,15 @@
//
//===----------------------------------------------------------------------===//
+// <experimental/tuple>
+
+#include <experimental/tuple>
+
int main()
{
+#if _LIBCPP_STD_VER > 11
+# ifndef _LIBCPP_TUPLE
+# error "<experimental/tuple> must include <tuple>"
+# endif
+#endif /* _LIBCPP_STD_VER > 11 */
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/libcxx/experimental/utilities/tuple/version.pass.cpp
similarity index 74%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/libcxx/experimental/utilities/tuple/version.pass.cpp
index b58f5c5..5a3fd2e 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/libcxx/experimental/utilities/tuple/version.pass.cpp
@@ -7,6 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// <experimental/tuple>
+
+#include <experimental/tuple>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
int main()
{
}
diff --git a/test/libcxx/selftest/test_macros.pass.cpp b/test/libcxx/selftest/test_macros.pass.cpp
new file mode 100644
index 0000000..2c8ed4f
--- /dev/null
+++ b/test/libcxx/selftest/test_macros.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test the "test_macros.h" header.
+#include "test_macros.h"
+
+#ifndef TEST_STD_VER
+#error TEST_STD_VER must be defined
+#endif
+
+#ifndef TEST_DECLTYPE
+#error TEST_DECLTYPE must be defined
+#endif
+
+#ifndef TEST_NOEXCEPT
+#error TEST_NOEXCEPT must be defined
+#endif
+
+#ifndef TEST_STATIC_ASSERT
+#error TEST_STATIC_ASSERT must be defined
+#endif
+
+template <class T, class U>
+struct is_same { enum { value = 0 }; };
+
+template <class T>
+struct is_same<T, T> { enum { value = 1 }; };
+
+int foo() { return 0; }
+
+void test_noexcept() TEST_NOEXCEPT
+{
+}
+
+void test_decltype()
+{
+ typedef TEST_DECLTYPE(foo()) MyType;
+ TEST_STATIC_ASSERT((is_same<MyType, int>::value), "is same");
+}
+
+void test_static_assert()
+{
+ TEST_STATIC_ASSERT((is_same<int, int>::value), "is same");
+ TEST_STATIC_ASSERT((!is_same<int, long>::value), "not same");
+}
+
+int main()
+{
+ test_noexcept();
+ test_decltype();
+ test_static_assert();
+}
diff --git a/test/libcxx/test/config.py b/test/libcxx/test/config.py
index 6bf1d60..502b688 100644
--- a/test/libcxx/test/config.py
+++ b/test/libcxx/test/config.py
@@ -52,6 +52,7 @@
self.libcxx_src_root = None
self.libcxx_obj_root = None
self.cxx_library_root = None
+ self.abi_library_root = None
self.env = {}
self.use_target = False
self.use_system_cxx_lib = False
@@ -90,13 +91,14 @@
self.configure_use_clang_verify()
self.configure_execute_external()
self.configure_ccache()
- self.configure_env()
self.configure_compile_flags()
self.configure_link_flags()
+ self.configure_env()
self.configure_color_diagnostics()
self.configure_debug_mode()
self.configure_warnings()
self.configure_sanitizer()
+ self.configure_coverage()
self.configure_substitutions()
self.configure_features()
@@ -199,8 +201,10 @@
'''If set, run clang with -verify on failing tests.'''
self.use_clang_verify = self.get_lit_bool('use_clang_verify')
if self.use_clang_verify is None:
- # TODO: Default this to True when using clang.
- self.use_clang_verify = False
+ # NOTE: We do not test for the -verify flag directly because
+ # -verify will always exit with non-zero on an empty file.
+ self.use_clang_verify = self.cxx.hasCompileFlag(
+ ['-Xclang', '-verify-ignore-unexpected'])
self.lit_config.note(
"inferred use_clang_verify as: %r" % self.use_clang_verify)
@@ -221,7 +225,8 @@
self.execute_external = not use_lit_shell
def configure_ccache(self):
- use_ccache = self.get_lit_bool('use_ccache', False)
+ use_ccache_default = os.environ.get('LIBCXX_USE_CCACHE') is not None
+ use_ccache = self.get_lit_bool('use_ccache', use_ccache_default)
if use_ccache:
self.cxx.use_ccache = True
self.lit_config.note('enabling ccache')
@@ -322,6 +327,11 @@
if self.long_tests:
self.config.available_features.add('long_tests')
+ # Run a compile test for the -fsized-deallocation flag. This is needed
+ # in test/std/language.support/support.dynamic/new.delete
+ if self.cxx.hasCompileFlag('-fsized-deallocation'):
+ self.config.available_features.add('fsized-deallocation')
+
def configure_compile_flags(self):
no_default_flags = self.get_lit_bool('no_default_flags', False)
if not no_default_flags:
@@ -347,6 +357,9 @@
# Configure feature flags.
self.configure_compile_flags_exceptions()
self.configure_compile_flags_rtti()
+ self.configure_compile_flags_no_global_filesystem_namespace()
+ self.configure_compile_flags_no_stdin()
+ self.configure_compile_flags_no_stdout()
enable_32bit = self.get_lit_bool('enable_32bit', False)
if enable_32bit:
self.cxx.flags += ['-m32']
@@ -361,6 +374,8 @@
elif not enable_monotonic_clock:
self.lit_config.fatal('enable_monotonic_clock cannot be false when'
' enable_threads is true.')
+ self.configure_compile_flags_no_thread_unsafe_c_functions()
+
# Use verbose output for better errors
self.cxx.flags += ['-v']
sysroot = self.get_lit_conf('sysroot')
@@ -372,15 +387,6 @@
if self.use_target:
self.cxx.flags += ['-target', self.config.target_triple]
- sysroot = self.get_lit_conf('sysroot')
- if sysroot:
- self.compile_flags += ['--sysroot', sysroot]
- gcc_toolchain = self.get_lit_conf('gcc_toolchain')
- if gcc_toolchain:
- self.compile_flags += ['-gcc-toolchain', gcc_toolchain]
-
- self.compile_flags += ['-target', self.config.target_triple]
-
def configure_compile_flags_header_includes(self):
support_path = os.path.join(self.libcxx_src_root, 'test/support')
self.cxx.compile_flags += ['-I' + support_path]
@@ -404,10 +410,40 @@
self.config.available_features.add('libcpp-no-rtti')
self.cxx.compile_flags += ['-fno-rtti', '-D_LIBCPP_NO_RTTI']
+ def configure_compile_flags_no_global_filesystem_namespace(self):
+ enable_global_filesystem_namespace = self.get_lit_bool(
+ 'enable_global_filesystem_namespace', True)
+ if not enable_global_filesystem_namespace:
+ self.config.available_features.add(
+ 'libcpp-has-no-global-filesystem-namespace')
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE']
+
+ def configure_compile_flags_no_stdin(self):
+ enable_stdin = self.get_lit_bool('enable_stdin', True)
+ if not enable_stdin:
+ self.config.available_features.add('libcpp-has-no-stdin')
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDIN']
+
+ def configure_compile_flags_no_stdout(self):
+ enable_stdout = self.get_lit_bool('enable_stdout', True)
+ if not enable_stdout:
+ self.config.available_features.add('libcpp-has-no-stdout')
+ self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDOUT']
+
def configure_compile_flags_no_threads(self):
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS']
self.config.available_features.add('libcpp-has-no-threads')
+ def configure_compile_flags_no_thread_unsafe_c_functions(self):
+ enable_thread_unsafe_c_functions = self.get_lit_bool(
+ 'enable_thread_unsafe_c_functions', True)
+ if not enable_thread_unsafe_c_functions:
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS']
+ self.config.available_features.add(
+ 'libcpp-has-no-thread-unsafe-c-functions')
+
def configure_compile_flags_no_monotonic_clock(self):
self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK']
self.config.available_features.add('libcpp-has-no-monotonic-clock')
@@ -450,10 +486,10 @@
def configure_link_flags_abi_library_path(self):
# Configure ABI library paths.
- abi_library_path = self.get_lit_conf('abi_library_path', '')
- if abi_library_path:
- self.cxx.link_flags += ['-L' + abi_library_path,
- '-Wl,-rpath,' + abi_library_path]
+ self.abi_library_root = self.get_lit_conf('abi_library_path')
+ if self.abi_library_root:
+ self.cxx.link_flags += ['-L' + self.abi_library_root,
+ '-Wl,-rpath,' + self.abi_library_root]
def configure_link_flags_cxx_library(self):
libcxx_library = self.get_lit_conf('libcxx_library')
@@ -499,7 +535,7 @@
else:
self.cxx.link_flags += ['-lgcc_s']
elif target_platform.startswith('freebsd'):
- self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s']
+ self.cxx.link_flags += ['-lc', '-lm', '-lpthread', '-lgcc_s', '-lcxxrt']
else:
self.lit_config.fatal("unrecognized system: %r" % target_platform)
@@ -512,7 +548,15 @@
if use_color != '':
self.lit_config.fatal('Invalid value for color_diagnostics "%s".'
% use_color)
- self.cxx.flags += ['-fdiagnostics-color=always']
+ color_flag = '-fdiagnostics-color=always'
+ # Check if the compiler supports the color diagnostics flag. Issue a
+ # warning if it does not since color diagnostics have been requested.
+ if not self.cxx.hasCompileFlag(color_flag):
+ self.lit_config.warning(
+ 'color diagnostics have been requested but are not supported '
+ 'by the compiler')
+ else:
+ self.cxx.flags += [color_flag]
def configure_debug_mode(self):
debug_level = self.get_lit_conf('debug_level', None)
@@ -526,10 +570,20 @@
def configure_warnings(self):
enable_warnings = self.get_lit_bool('enable_warnings', False)
if enable_warnings:
- self.cxx.compile_flags += ['-Wsystem-headers', '-Wall', '-Werror']
- if ('clang' in self.config.available_features or
- 'apple-clang' in self.config.available_features):
- self.cxx.compile_flags += ['-Wno-user-defined-literals']
+ self.cxx.compile_flags += [
+ '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER',
+ '-Wall', '-Werror'
+ ]
+ self.cxx.addCompileFlagIfSupported('-Wno-attributes')
+ if self.cxx.type == 'clang' or self.cxx.type == 'apple-clang':
+ self.cxx.addCompileFlagIfSupported('-Wno-pessimizing-move')
+ self.cxx.addCompileFlagIfSupported('-Wno-c++11-extensions')
+ self.cxx.addCompileFlagIfSupported('-Wno-user-defined-literals')
+ std = self.get_lit_conf('std', None)
+ if std in ['c++98', 'c++03']:
+ # The '#define static_assert' provided by libc++ in C++03 mode
+ # causes an unused local typedef whenever it is used.
+ self.cxx.addCompileFlagIfSupported('-Wno-unused-local-typedef')
def configure_sanitizer(self):
san = self.get_lit_conf('use_sanitizer', '').strip()
@@ -553,6 +607,7 @@
if llvm_symbolizer is not None:
self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
self.config.available_features.add('asan')
+ self.config.available_features.add('sanitizer-new-delete')
elif san == 'Memory' or san == 'MemoryWithOrigins':
self.cxx.flags += ['-fsanitize=memory']
if san == 'MemoryWithOrigins':
@@ -561,18 +616,32 @@
if llvm_symbolizer is not None:
self.env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
self.config.available_features.add('msan')
+ self.config.available_features.add('sanitizer-new-delete')
elif san == 'Undefined':
self.cxx.flags += ['-fsanitize=undefined',
'-fno-sanitize=vptr,function',
'-fno-sanitize-recover']
self.cxx.compile_flags += ['-O3']
self.config.available_features.add('ubsan')
+ if self.target_info.platform() == 'darwin':
+ self.config.available_features.add('sanitizer-new-delete')
elif san == 'Thread':
self.cxx.flags += ['-fsanitize=thread']
self.config.available_features.add('tsan')
+ self.config.available_features.add('sanitizer-new-delete')
else:
self.lit_config.fatal('unsupported value for '
'use_sanitizer: {0}'.format(san))
+ san_lib = self.get_lit_conf('sanitizer_library')
+ if san_lib:
+ self.cxx.link_flags += [
+ san_lib, '-Wl,-rpath,%s' % os.path.dirname(san_lib)]
+
+ def configure_coverage(self):
+ self.generate_coverage = self.get_lit_bool('generate_coverage', False)
+ if self.generate_coverage:
+ self.cxx.flags += ['-g', '--coverage']
+ self.cxx.compile_flags += ['-O0']
def configure_substitutions(self):
sub = self.config.substitutions
@@ -639,12 +708,18 @@
"inferred target_triple as: %r" % self.config.target_triple)
def configure_env(self):
- if (self.target_info.platform() == 'darwin' and
- not self.use_system_cxx_lib):
+ if self.target_info.platform() == 'darwin':
+ library_paths = []
+ # Configure the library path for libc++
libcxx_library = self.get_lit_conf('libcxx_library')
- if libcxx_library:
- cxx_library_root = os.path.dirname(libcxx_library)
- else:
- cxx_library_root = self.cxx_library_root
- if cxx_library_root:
- self.env['DYLD_LIBRARY_PATH'] = cxx_library_root
+ if self.use_system_cxx_lib:
+ pass
+ elif libcxx_library:
+ library_paths += [os.path.dirname(libcxx_library)]
+ elif self.cxx_library_root:
+ library_paths += [self.cxx_library_root]
+ # Configure the abi library path
+ if self.abi_library_root:
+ library_paths += [self.abi_library_root]
+ if library_paths:
+ self.env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
diff --git a/test/libcxx/test/executor.py b/test/libcxx/test/executor.py
index 492f934..f0356ce 100644
--- a/test/libcxx/test/executor.py
+++ b/test/libcxx/test/executor.py
@@ -17,7 +17,7 @@
file_deps: [str]: Files required by the test
env: {str: str}: Environment variables to execute under
Returns:
- out, err, exitCode
+ cmd, out, err, exitCode
"""
raise NotImplementedError
@@ -34,7 +34,8 @@
env_cmd += ['%s=%s' % (k, v) for k, v in env.items()]
if work_dir == '.':
work_dir = os.getcwd()
- return executeCommand(env_cmd + cmd, cwd=work_dir)
+ out, err, rc = executeCommand(env_cmd + cmd, cwd=work_dir)
+ return (env_cmd + cmd, out, err, rc)
class PrefixExecutor(Executor):
@@ -129,6 +130,9 @@
srcs.extend(file_deps)
dsts.extend(dev_paths)
self.copy_in(srcs, dsts)
+ # TODO(jroelofs): capture the copy_in and delete_remote commands,
+ # and conjugate them with '&&'s around the first tuple element
+ # returned here:
return self._execute_command_remote(cmd, target_cwd, env)
finally:
if target_cwd:
diff --git a/test/libcxx/test/format.py b/test/libcxx/test/format.py
index 921f02b..238dcdb 100644
--- a/test/libcxx/test/format.py
+++ b/test/libcxx/test/format.py
@@ -6,6 +6,7 @@
import lit.TestRunner # pylint: disable=import-error
import lit.util # pylint: disable=import-error
+from libcxx.test.executor import LocalExecutor as LocalExecutor
import libcxx.util
@@ -59,6 +60,10 @@
is_pass_test = name.endswith('.pass.cpp')
is_fail_test = name.endswith('.fail.cpp')
+ if test.config.unsupported:
+ return (lit.Test.UNSUPPORTED,
+ "A lit.local.cfg marked this unsupported")
+
res = lit.TestRunner.parseIntegratedTestScript(
test, require_script=is_sh_test)
# Check if a result for the test was returned. If so return that
@@ -75,7 +80,7 @@
# Dispatch the test based on its suffix.
if is_sh_test:
- if self.executor:
+ if not isinstance(self.executor, LocalExecutor):
# We can't run ShTest tests with a executor yet.
# For now, bail on trying to run them
return lit.Test.UNSUPPORTED, 'ShTest format not yet supported'
@@ -120,8 +125,8 @@
# should add a `// FILE-DEP: foo.dat` to each test to track this.
data_files = [os.path.join(local_cwd, f)
for f in os.listdir(local_cwd) if f.endswith('.dat')]
- out, err, rc = self.executor.run(exec_path, [exec_path],
- local_cwd, data_files, env)
+ cmd, out, err, rc = self.executor.run(exec_path, [exec_path],
+ local_cwd, data_files, env)
if rc != 0:
report = libcxx.util.makeReport(cmd, out, err, rc)
report = "Compiled With: %s\n%s" % (compile_cmd, report)
@@ -136,13 +141,16 @@
def _evaluate_fail_test(self, test):
source_path = test.getSourcePath()
- # TODO: Move the checking of USE_VERIFY into
- # lit.TestRunner.parseIntegratedTestScript by adding support for custom
- # tags.
with open(source_path, 'r') as f:
contents = f.read()
- use_verify = 'USE_VERIFY' in contents and self.use_verify_for_fail
- extra_flags = ['-Xclang', '-verify'] if use_verify else []
+ verify_tags = ['expected-note', 'expected-remark', 'expected-warning',
+ 'expected-error', 'expected-no-diagnostics']
+ use_verify = self.use_verify_for_fail and \
+ any([tag in contents for tag in verify_tags])
+ extra_flags = []
+ if use_verify:
+ extra_flags += ['-Xclang', '-verify',
+ '-Xclang', '-verify-ignore-unexpected=note']
cmd, out, err, rc = self.cxx.compile(source_path, out=os.devnull,
flags=extra_flags)
expected_rc = 0 if use_verify else 1
@@ -150,5 +158,6 @@
return lit.Test.PASS, ''
else:
report = libcxx.util.makeReport(cmd, out, err, rc)
- return (lit.Test.FAIL,
- report + 'Expected compilation to fail!\n')
+ report_msg = ('Expected compilation to fail!' if not use_verify else
+ 'Expected compilation using verify to pass!')
+ return lit.Test.FAIL, report + report_msg + '\n'
diff --git a/test/libcxx/type_traits/convert_to_integral.pass.cpp b/test/libcxx/type_traits/convert_to_integral.pass.cpp
index 37060a0..b97832b 100644
--- a/test/libcxx/type_traits/convert_to_integral.pass.cpp
+++ b/test/libcxx/type_traits/convert_to_integral.pass.cpp
@@ -1,4 +1,7 @@
+// TODO: Make this test pass for all standards.
+// XFAIL: c++98, c++03
+
#include <limits>
#include <type_traits>
#include <cstdint>
@@ -57,7 +60,7 @@
}
-enum enum1 {};
+enum enum1 { zero = 0, one = 1 };
enum enum2 {
value = std::numeric_limits<unsigned long>::max()
};
diff --git a/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
new file mode 100644
index 0000000..25dd311
--- /dev/null
+++ b/test/libcxx/utilities/memory/util.smartptr/race_condition.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+//
+// <memory>
+//
+// class shared_ptr
+//
+// This test attempts to create a race condition surrounding use_count()
+// with the hope that TSAN will diagnose it.
+
+#include <memory>
+#include <atomic>
+#include <thread>
+#include <cassert>
+
+typedef std::shared_ptr<int> Ptr;
+typedef std::weak_ptr<int> WeakPtr;
+
+std::atomic_bool Start;
+std::atomic_bool KeepRunning;
+
+struct TestRunner {
+ TestRunner(Ptr xx) : x(xx) {}
+ void operator()() {
+ while (Start == false) {}
+ while (KeepRunning) {
+ // loop to prevent always checking the atomic.
+ for (int i=0; i < 100000; ++i) {
+ Ptr x2 = x; // increment shared count
+ WeakPtr x3 = x; // increment weak count
+ Ptr x4 = x3.lock(); // increment shared count via lock
+ WeakPtr x5 = x3; // increment weak count
+ }
+ }
+ }
+ Ptr x;
+};
+
+void run_test(Ptr p) {
+ Start = false;
+ KeepRunning = true;
+ assert(p.use_count() == 2);
+ TestRunner r(p);
+ assert(p.use_count() == 3);
+ std::thread t1(r); // Start the test thread.
+ assert(p.use_count() == 4);
+ Start = true;
+ // Run until we witness 25 use count changes via both
+ // shared and weak pointer methods.
+ WeakPtr w = p;
+ int shared_changes_count = 0;
+ int weak_changes_count = 0;
+ while (shared_changes_count < 25 && weak_changes_count < 25) {
+ // check use_count on the shared_ptr
+ int last = p.use_count();
+ int new_val = p.use_count();
+ assert(last >= 4);
+ assert(new_val >= 4);
+ if (last != new_val) ++shared_changes_count;
+ // Check use_count on the weak_ptr
+ last = w.use_count();
+ new_val = w.use_count();
+ assert(last >= 4);
+ assert(new_val >= 4);
+ if (last != new_val) ++weak_changes_count;
+ }
+ // kill the test thread.
+ KeepRunning = false;
+ t1.join();
+ assert(p.use_count() == 3);
+}
+
+int main() {
+ {
+ // Test with out-of-place shared_count.
+ Ptr p(new int(42));
+ run_test(p);
+ assert(p.use_count() == 1);
+ }
+ {
+ // Test with in-place shared_count.
+ Ptr p = std::make_shared<int>(42);
+ run_test(p);
+ assert(p.use_count() == 1);
+ }
+}
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 5a4445b..765ee7c 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -1,6 +1,5 @@
@AUTO_GEN_COMMENT@
config.cxx_under_test = "@LIBCXX_COMPILER@"
-config.std = "@LIBCXX_STD_VERSION@"
config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@"
config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@"
config.cxx_library_root = "@LIBCXX_LIBRARY_DIR@"
@@ -8,17 +7,24 @@
config.enable_rtti = "@LIBCXX_ENABLE_RTTI@"
config.enable_shared = "@LIBCXX_ENABLE_SHARED@"
config.enable_32bit = "@LIBCXX_BUILD_32_BITS@"
+config.enable_global_filesystem_namespace = "@LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE@"
+config.enable_stdin = "@LIBCXX_ENABLE_STDIN@"
+config.enable_stdout = "@LIBCXX_ENABLE_STDOUT@"
config.enable_threads = "@LIBCXX_ENABLE_THREADS@"
+config.enable_thread_unsafe_c_functions = "@LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS@"
config.enable_monotonic_clock = "@LIBCXX_ENABLE_MONOTONIC_CLOCK@"
config.cxx_abi = "@LIBCXX_CXX_ABI_LIBNAME@"
config.use_sanitizer = "@LLVM_USE_SANITIZER@"
+config.sanitizer_library = "@LIBCXX_SANITIZER_LIBRARY@"
config.abi_library_path = "@LIBCXX_CXX_ABI_LIBRARY_PATH@"
config.configuration_variant = "@LIBCXX_LIT_VARIANT@"
config.target_triple = "@LIBCXX_TARGET_TRIPLE@"
config.sysroot = "@LIBCXX_SYSROOT@"
config.gcc_toolchain = "@LIBCXX_GCC_TOOLCHAIN@"
+config.generate_coverage = "@LIBCXX_GENERATE_COVERAGE@"
config.target_info = "@LIBCXX_TARGET_INFO@"
config.executor = "@LIBCXX_EXECUTOR@"
+config.llvm_unwinder = "@LIBCXXABI_USE_LLVM_UNWINDER@"
# Let the main config do the real work.
lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg")
diff --git a/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp b/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
index 7810dec..cf23c77 100644
--- a/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
+++ b/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
@@ -17,10 +17,9 @@
#include <algorithm>
#include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#include <memory>
-#endif
+#include "test_macros.h"
#include "test_iterators.h"
struct is_odd
@@ -283,7 +282,7 @@
}
}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
struct is_null
{
@@ -298,9 +297,10 @@
const unsigned size = 5;
std::unique_ptr<int> array[size];
Iter r = std::stable_partition(Iter(array), Iter(array+size), is_null());
+ assert(r == Iter(array+size));
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif // TEST_STD_VER >= 11
int main()
{
@@ -308,7 +308,7 @@
test<random_access_iterator<std::pair<int,int>*> >();
test<std::pair<int,int>*>();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test1<bidirectional_iterator<std::unique_ptr<int>*> >();
#endif
}
diff --git a/test/std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp b/test/std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
index abc89dc..eb37cca 100644
--- a/test/std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
+++ b/test/std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
@@ -17,18 +17,16 @@
#include <algorithm>
#include <cassert>
+#include "test_macros.h"
#include "test_iterators.h"
-#if _LIBCPP_STD_VER > 11
-#define HAS_FOUR_ITERATOR_VERSION
-#endif
int main()
{
int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};
- const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+ const unsigned sb = sizeof(ib)/sizeof(ib[0]); ((void)sb); // unused in c++11
typedef input_iterator<const int*> II;
typedef random_access_iterator<const int*> RAI;
@@ -39,7 +37,7 @@
assert(std::mismatch(RAI(ia), RAI(ia + sa), RAI(ib))
== (std::pair<RAI, RAI>(RAI(ia+3), RAI(ib+3))));
-#ifdef HAS_FOUR_ITERATOR_VERSION
+#if TEST_STD_VER > 11 // We have the four iteration version
assert(std::mismatch(II(ia), II(ia + sa), II(ib), II(ib+sb))
== (std::pair<II, II>(II(ia+3), II(ib+3))));
diff --git a/test/std/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp b/test/std/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
index 8d85d99..3e1dfd1 100644
--- a/test/std/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
+++ b/test/std/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp
@@ -19,10 +19,11 @@
#include <functional>
#include <cassert>
+#include "test_macros.h"
#include "test_iterators.h"
#include "counting_predicates.hpp"
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
#define HAS_FOUR_ITERATOR_VERSION
#endif
@@ -31,7 +32,7 @@
int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};
const unsigned sa = sizeof(ia)/sizeof(ia[0]);
int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};
- const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+ const unsigned sb = sizeof(ib)/sizeof(ib[0]); ((void)sb); // unused in c++11
typedef input_iterator<const int*> II;
typedef random_access_iterator<const int*> RAI;
diff --git a/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp b/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
index 01db088..8291573 100644
--- a/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp
@@ -20,12 +20,35 @@
#include "test_iterators.h"
+#if TEST_STD_VER >= 11
+struct S {
+ S() : i_(0) {}
+ S(int i) : i_(i) {}
+
+ S(const S& rhs) : i_(rhs.i_) {}
+ S( S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
+
+ S& operator =(const S& rhs) { i_ = rhs.i_; return *this; }
+ S& operator =( S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; }
+ S& operator =(int i) { i_ = i; return *this; }
+
+ bool operator <(const S& rhs) const { return i_ < rhs.i_; }
+ bool operator ==(const S& rhs) const { return i_ == rhs.i_; }
+ bool operator ==(int i) const { return i_ == i; }
+
+ void set(int i) { i_ = i; }
+
+ int i_;
+ };
+#endif
+
template <class Iter>
void
test_one(unsigned N, unsigned M)
{
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
assert(M <= N);
- int* ia = new int[N];
+ value_type* ia = new value_type[N];
for (unsigned i = 0; i < N; ++i)
ia[i] = i;
std::random_shuffle(ia, ia+N);
@@ -76,4 +99,10 @@
test<bidirectional_iterator<int*> >();
test<random_access_iterator<int*> >();
test<int*>();
+
+#if TEST_STD_VER >= 11
+ test<bidirectional_iterator<S*> >();
+ test<random_access_iterator<S*> >();
+ test<S*>();
+#endif // TEST_STD_VER >= 11
}
diff --git a/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
index b54efb6..ca6f8e4 100644
--- a/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
@@ -18,7 +18,10 @@
#include <algorithm>
#include <functional>
#include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 11
#include <memory>
struct indirect_less
@@ -28,7 +31,29 @@
{return *x < *y;}
};
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+struct S {
+ S() : i_(0) {}
+ S(int i) : i_(i) {}
+
+ S(const S& rhs) : i_(rhs.i_) {}
+ S( S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }
+
+ S& operator =(const S& rhs) { i_ = rhs.i_; return *this; }
+ S& operator =( S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; }
+ S& operator =(int i) { i_ = i; return *this; }
+
+ bool operator <(const S& rhs) const { return i_ < rhs.i_; }
+ bool operator >(const S& rhs) const { return i_ > rhs.i_; }
+ bool operator ==(const S& rhs) const { return i_ == rhs.i_; }
+ bool operator ==(int i) const { return i_ == i; }
+
+ void set(int i) { i_ = i; }
+
+ int i_;
+ };
+
+
+#endif // TEST_STD_VER >= 11
#include "test_iterators.h"
#include "counting_predicates.hpp"
@@ -38,19 +63,20 @@
test_one(unsigned N, unsigned M)
{
assert(M <= N);
- int* ia = new int[N];
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+ value_type* ia = new value_type[N];
for (unsigned i = 0; i < N; ++i)
ia[i] = i;
std::random_shuffle(ia, ia+N);
- std::sort(ia, ia+M, std::greater<int>());
- std::sort(ia+M, ia+N, std::greater<int>());
- binary_counting_predicate<std::greater<int>, int, int> pred((std::greater<int>()));
+ std::sort(ia, ia+M, std::greater<value_type>());
+ std::sort(ia+M, ia+N, std::greater<value_type>());
+ binary_counting_predicate<std::greater<value_type>, value_type, value_type> pred((std::greater<value_type>()));
std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N), std::ref(pred));
if(N > 0)
{
assert(ia[0] == N-1);
assert(ia[N-1] == 0);
- assert(std::is_sorted(ia, ia+N, std::greater<int>()));
+ assert(std::is_sorted(ia, ia+N, std::greater<value_type>()));
assert(pred.count() <= (N-1));
}
delete [] ia;
@@ -93,7 +119,11 @@
test<random_access_iterator<int*> >();
test<int*>();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
+ test<bidirectional_iterator<S*> >();
+ test<random_access_iterator<S*> >();
+ test<S*>();
+
{
unsigned N = 100;
unsigned M = 50;
@@ -112,5 +142,5 @@
}
delete [] ia;
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif // TEST_STD_VER >= 11
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp
index 2788b19..2197b97 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/max_element.pass.cpp
@@ -57,10 +57,24 @@
test<Iter>(1000);
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::max_element(il,il+8);
+ static_assert ( *p == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test ();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp
index 74e9fe6..37c1813 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/max_element_comp.pass.cpp
@@ -75,6 +75,19 @@
delete [] a;
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::max_element(il, il+8, less());
+ static_assert ( *p == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
@@ -82,4 +95,6 @@
test<random_access_iterator<const int*> >();
test<const int*>();
test_eq();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp
index fd41f7a..a9a9d61 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/min_element.pass.cpp
@@ -57,10 +57,24 @@
test<Iter>(1000);
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::min_element(il, il+8);
+ static_assert ( *p == 1, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp
index 2b5fdb1..9517f7e 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/min_element_comp.pass.cpp
@@ -75,6 +75,19 @@
delete [] a;
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::min_element(il, il+8, less());
+ static_assert(*p == 1, "");
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
@@ -82,4 +95,6 @@
test<random_access_iterator<const int*> >();
test<const int*>();
test_eq();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp
index 6cdb87d..915b1d1 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element.pass.cpp
@@ -74,10 +74,25 @@
}
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::minmax_element(il, il+8);
+ static_assert ( *(p.first) == 1, "" );
+ static_assert ( *(p.second) == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp
index cc0e66e..d3a067f 100644
--- a/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.min.max/minmax_element_comp.pass.cpp
@@ -79,10 +79,26 @@
}
}
+#if __cplusplus >= 201402L
+constexpr int il[] = { 2, 4, 6, 8, 7, 5, 3, 1 };
+struct less { constexpr bool operator ()( const int &x, const int &y) const { return x < y; }};
+#endif
+
+void constexpr_test()
+{
+#if __cplusplus >= 201402L
+ constexpr auto p = std::minmax_element(il, il+8, less());
+ static_assert ( *(p.first) == 1, "" );
+ static_assert ( *(p.second) == 8, "" );
+#endif
+}
+
int main()
{
test<forward_iterator<const int*> >();
test<bidirectional_iterator<const int*> >();
test<random_access_iterator<const int*> >();
test<const int*>();
+
+ constexpr_test();
}
diff --git a/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes.pass.cpp b/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes.pass.cpp
index 8db8177..70abd18 100644
--- a/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes.pass.cpp
@@ -29,9 +29,9 @@
int ib[] = {2, 4};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int ic[] = {1, 2};
- const unsigned sc = sizeof(ic)/sizeof(ic[0]);
+ const unsigned sc = sizeof(ic)/sizeof(ic[0]); ((void)sc);
int id[] = {3, 3, 3, 3};
- const unsigned sd = sizeof(id)/sizeof(id[0]);
+ const unsigned sd = sizeof(id)/sizeof(id[0]); ((void)sd);
assert(std::includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib)));
assert(!std::includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib+1)));
diff --git a/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes_comp.pass.cpp
index 7e1aef4..299dc89 100644
--- a/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes_comp.pass.cpp
+++ b/test/std/algorithms/alg.sorting/alg.set.operations/includes/includes_comp.pass.cpp
@@ -30,9 +30,9 @@
int ib[] = {2, 4};
const unsigned sb = sizeof(ib)/sizeof(ib[0]);
int ic[] = {1, 2};
- const unsigned sc = sizeof(ic)/sizeof(ic[0]);
+ const unsigned sc = sizeof(ic)/sizeof(ic[0]); ((void)sc);
int id[] = {3, 3, 3, 3};
- const unsigned sd = sizeof(id)/sizeof(id[0]);
+ const unsigned sd = sizeof(id)/sizeof(id[0]); ((void)sd);
assert(std::includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib), std::less<int>()));
assert(!std::includes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib+1), std::less<int>()));
diff --git a/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp b/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
index 64093d6..8a60f81 100644
--- a/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
+++ b/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp
@@ -22,13 +22,13 @@
int main()
{
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear(&f);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear(&f);
assert(f.test_and_set() == 0);
diff --git a/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp b/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
index e1a9349..92e57ec 100644
--- a/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
+++ b/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
@@ -22,37 +22,37 @@
int main()
{
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_relaxed);
assert(f.test_and_set() == 0);
}
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_release);
assert(f.test_and_set() == 0);
}
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_seq_cst);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_relaxed);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_release);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_seq_cst);
assert(f.test_and_set() == 0);
diff --git a/test/std/atomics/atomics.flag/clear.pass.cpp b/test/std/atomics/atomics.flag/clear.pass.cpp
index 65051af..7c93626 100644
--- a/test/std/atomics/atomics.flag/clear.pass.cpp
+++ b/test/std/atomics/atomics.flag/clear.pass.cpp
@@ -22,49 +22,49 @@
int main()
{
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear();
assert(f.test_and_set() == 0);
}
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear(std::memory_order_relaxed);
assert(f.test_and_set() == 0);
}
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear(std::memory_order_release);
assert(f.test_and_set() == 0);
}
{
- std::atomic_flag f;
+ std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear(std::memory_order_seq_cst);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear();
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear(std::memory_order_relaxed);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear(std::memory_order_release);
assert(f.test_and_set() == 0);
}
{
- volatile std::atomic_flag f;
+ volatile std::atomic_flag f = ATOMIC_FLAG_INIT;
f.test_and_set();
f.clear(std::memory_order_seq_cst);
assert(f.test_and_set() == 0);
diff --git a/test/std/atomics/atomics.flag/default.pass.cpp b/test/std/atomics/atomics.flag/default.pass.cpp
index 45f5e70..11c08f5 100644
--- a/test/std/atomics/atomics.flag/default.pass.cpp
+++ b/test/std/atomics/atomics.flag/default.pass.cpp
@@ -22,7 +22,8 @@
int main()
{
std::atomic_flag f;
-
+ f.clear();
+ assert(f.test_and_set() == 0);
{
typedef std::atomic_flag A;
_ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
diff --git a/test/std/atomics/atomics.types.generic/address.pass.cpp b/test/std/atomics/atomics.types.generic/address.pass.cpp
index 3b9f3ce..eceac25 100644
--- a/test/std/atomics/atomics.types.generic/address.pass.cpp
+++ b/test/std/atomics/atomics.types.generic/address.pass.cpp
@@ -81,12 +81,13 @@
{
typedef typename std::remove_pointer<T>::type X;
A obj(T(0));
+ bool b0 = obj.is_lock_free();
+ ((void)b0); // mark as unused
assert(obj == T(0));
std::atomic_init(&obj, T(1));
assert(obj == T(1));
std::atomic_init(&obj, T(2));
assert(obj == T(2));
- bool b0 = obj.is_lock_free();
obj.store(T(0));
assert(obj == T(0));
obj.store(T(1), std::memory_order_release);
diff --git a/test/std/atomics/atomics.types.generic/bool.pass.cpp b/test/std/atomics/atomics.types.generic/bool.pass.cpp
index dd851e8..8eb04ee 100644
--- a/test/std/atomics/atomics.types.generic/bool.pass.cpp
+++ b/test/std/atomics/atomics.types.generic/bool.pass.cpp
@@ -60,7 +60,6 @@
int main()
{
{
- volatile std::atomic<bool> _;
volatile std::atomic<bool> obj(true);
assert(obj == true);
std::atomic_init(&obj, false);
@@ -116,7 +115,6 @@
assert(obj == true);
}
{
- std::atomic<bool> _;
std::atomic<bool> obj(true);
assert(obj == true);
std::atomic_init(&obj, false);
@@ -172,7 +170,6 @@
assert(obj == true);
}
{
- std::atomic_bool _;
std::atomic_bool obj(true);
assert(obj == true);
std::atomic_init(&obj, false);
diff --git a/test/std/atomics/atomics.types.generic/integral.pass.cpp b/test/std/atomics/atomics.types.generic/integral.pass.cpp
index f9c7583..802a37c 100644
--- a/test/std/atomics/atomics.types.generic/integral.pass.cpp
+++ b/test/std/atomics/atomics.types.generic/integral.pass.cpp
@@ -103,6 +103,7 @@
std::atomic_init(&obj, T(2));
assert(obj == T(2));
bool b0 = obj.is_lock_free();
+ ((void)b0); // mark as unused
obj.store(T(0));
assert(obj == T(0));
obj.store(T(1), std::memory_order_release);
diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
index 18a1605..ee22912 100644
--- a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
+++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
@@ -20,6 +20,7 @@
// atomic_is_lock_free(const atomic<T>* obj);
#include <atomic>
+#include <cassert>
template <class T>
void
@@ -30,6 +31,7 @@
bool b1 = std::atomic_is_lock_free(static_cast<const A*>(&t));
volatile A vt;
bool b2 = std::atomic_is_lock_free(static_cast<const volatile A*>(&vt));
+ assert(b1 == b2);
}
struct A
diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
new file mode 100644
index 0000000..f85172a
--- /dev/null
+++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
+
+// NOTE: atomic<> of a TriviallyCopyable class is wrongly rejected by older
+// clang versions. It was fixed right before the llvm 3.5 release. See PR18097.
+// XFAIL: apple-clang-6.0, clang-3.4, clang-3.3
+
+// <atomic>
+
+// constexpr atomic<T>::atomic(T value)
+
+#include <atomic>
+#include <type_traits>
+#include <cassert>
+
+struct UserType {
+ int i;
+
+ UserType() noexcept {}
+ constexpr explicit UserType(int d) noexcept : i(d) {}
+
+ friend bool operator==(const UserType& x, const UserType& y) {
+ return x.i == y.i;
+ }
+};
+
+template <class Tp>
+void test() {
+ typedef std::atomic<Tp> Atomic;
+ static_assert(std::is_literal_type<Atomic>::value, "");
+ constexpr Tp t(42);
+ {
+ constexpr Atomic a(t);
+ assert(a == t);
+ }
+ {
+ constexpr Atomic a{t};
+ assert(a == t);
+ }
+ {
+ constexpr Atomic a = ATOMIC_VAR_INIT(t);
+ assert(a == t);
+ }
+}
+
+
+int main()
+{
+ test<int>();
+ test<UserType>();
+}
diff --git a/test/std/containers/associative/map/compare.pass.cpp b/test/std/containers/associative/map/compare.pass.cpp
index aa4d599..26ac7af 100644
--- a/test/std/containers/associative/map/compare.pass.cpp
+++ b/test/std/containers/associative/map/compare.pass.cpp
@@ -17,16 +17,36 @@
// http://llvm.org/bugs/show_bug.cgi?id=16549
#include <map>
+#include <utility>
+#include <cassert>
struct Key {
template <typename T> Key(const T&) {}
bool operator< (const Key&) const { return false; }
};
-int
-main()
+int main()
{
- std::map<Key, int>::iterator it = std::map<Key, int>().find(Key(0));
- std::pair<std::map<Key, int>::iterator, bool> result =
- std::map<Key, int>().insert(std::make_pair(Key(0), 0));
+ typedef std::map<Key, int> MapT;
+ typedef MapT::iterator Iter;
+ typedef std::pair<Iter, bool> IterBool;
+ {
+ MapT m_empty;
+ MapT m_contains;
+ m_contains[Key(0)] = 42;
+
+ Iter it = m_empty.find(Key(0));
+ assert(it == m_empty.end());
+ it = m_contains.find(Key(0));
+ assert(it != m_contains.end());
+ }
+ {
+ MapT map;
+ IterBool result = map.insert(std::make_pair(Key(0), 42));
+ assert(result.second);
+ assert(result.first->second = 42);
+ IterBool result2 = map.insert(std::make_pair(Key(0), 43));
+ assert(!result2.second);
+ assert(map[Key(0)] == 42);
+ }
}
diff --git a/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp b/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
index d14603e..7e0fd41 100644
--- a/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
+++ b/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
@@ -16,14 +16,14 @@
#include <map>
#include <cassert>
+#include "test_macros.h"
#include "MoveOnly.h"
#include "min_allocator.h"
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
{
- typedef std::pair<MoveOnly, double> V;
std::map<MoveOnly, double> m;
assert(m.size() == 0);
assert(m[1] == 0.0);
@@ -37,8 +37,6 @@
assert(m[6] == 6.5);
assert(m.size() == 2);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#if __cplusplus >= 201103L
{
typedef std::pair<MoveOnly, double> V;
std::map<MoveOnly, double, std::less<MoveOnly>, min_allocator<V>> m;
diff --git a/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp b/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
index 05fb988..15c5ce0 100644
--- a/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
+++ b/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
@@ -18,6 +18,14 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator<(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+
int main()
{
{
@@ -234,4 +242,18 @@
assert(i == m.end());
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::map<T, int> C;
+ typedef C::iterator I;
+
+ C c;
+ T a{0};
+ I it = c.find(a);
+ if (it != c.end())
+ c.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp b/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp
new file mode 100644
index 0000000..484ed06
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// template <class M>
+// pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
+// template <class M>
+// pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
+// template <class M>
+// iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
+// template <class M>
+// iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
+
+#include <__config>
+#include <map>
+#include <cassert>
+#include <tuple>
+
+#include <iostream>
+
+class Moveable
+{
+ Moveable(const Moveable&);
+ Moveable& operator=(const Moveable&);
+
+ int int_;
+ double double_;
+public:
+ Moveable() : int_(0), double_(0) {}
+ Moveable(int i, double d) : int_(i), double_(d) {}
+ Moveable(Moveable&& x)
+ : int_(x.int_), double_(x.double_)
+ {x.int_ = -1; x.double_ = -1;}
+ Moveable& operator=(Moveable&& x)
+ {int_ = x.int_; x.int_ = -1;
+ double_ = x.double_; x.double_ = -1;
+ return *this;
+ }
+
+ bool operator==(const Moveable& x) const
+ {return int_ == x.int_ && double_ == x.double_;}
+ bool operator<(const Moveable& x) const
+ {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
+
+ int get() const {return int_;}
+ bool moved() const {return int_ == -1;}
+};
+
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+ { // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
+ typedef std::map<int, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+
+ for (int i=0; i < 20; i += 2)
+ {
+ Moveable mv(i+1, i+1);
+ r = m.insert_or_assign(i, std::move(mv));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(mv.moved()); // was moved from
+ assert(r.first->first == i); // key
+ assert(r.first->second.get() == i+1); // value
+ }
+
+ Moveable mv1(5, 5.0);
+ r = m.insert_or_assign(-1, std::move(mv1));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv1.moved()); // was moved from
+ assert(r.first->first == -1); // key
+ assert(r.first->second.get() == 5); // value
+
+ Moveable mv2(9, 9.0);
+ r = m.insert_or_assign(3, std::move(mv2));
+ assert(m.size() == 12);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(r.first->first == 3); // key
+ assert(r.first->second.get() == 9); // value
+
+ Moveable mv3(-1, 5.0);
+ r = m.insert_or_assign(117, std::move(mv3));
+ assert(m.size() == 13);
+ assert(r.second); // was inserted
+ assert(mv3.moved()); // was moved from
+ assert(r.first->first == 117); // key
+ assert(r.first->second.get() == -1); // value
+ }
+ { // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
+ typedef std::map<Moveable, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.insert_or_assign(std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(!mvkey1.moved()); // was not moved from
+ assert(mv1.moved()); // was moved from
+ assert(r.first->first == mvkey1); // key
+ assert(r.first->second.get() == 4); // value
+
+ Moveable mvkey2(3, 3.0);
+ Moveable mv2(5, 5.0);
+ r = m.try_emplace(std::move(mvkey2), std::move(mv2));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r.first->first.get() == 3); // key
+ assert(r.first->second.get() == 5); // value
+ }
+ { // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
+ typedef std::map<int, Moveable> M;
+ M m;
+ M::iterator r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+ M::const_iterator it = m.find(2);
+
+ Moveable mv1(3, 3.0);
+ r = m.insert_or_assign(it, 2, std::move(mv1));
+ assert(m.size() == 10);
+ assert(mv1.moved()); // was moved from
+ assert(r->first == 2); // key
+ assert(r->second.get() == 3); // value
+
+ Moveable mv2(5, 5.0);
+ r = m.insert_or_assign(it, 3, std::move(mv2));
+ assert(m.size() == 11);
+ assert(mv2.moved()); // was moved from
+ assert(r->first == 3); // key
+ assert(r->second.get() == 5); // value
+ }
+ { // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
+ typedef std::map<Moveable, Moveable> M;
+ M m;
+ M::iterator r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+ M::const_iterator it = std::next(m.cbegin());
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.insert_or_assign(it, std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(mv1.moved()); // was moved from
+ assert(!mvkey1.moved()); // was not moved from
+ assert(r->first == mvkey1); // key
+ assert(r->second.get() == 4); // value
+
+ Moveable mvkey2(3, 3.0);
+ Moveable mv2(5, 5.0);
+ r = m.insert_or_assign(it, std::move(mvkey2), std::move(mv2));
+ assert(m.size() == 11);
+ assert(mv2.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r->first.get() == 3); // key
+ assert(r->second.get() == 5); // value
+ }
+
+#endif // _LIBCPP_HAS_NO_VARIADICS
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp b/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp
new file mode 100644
index 0000000..8e0dd75
--- /dev/null
+++ b/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp
@@ -0,0 +1,189 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <map>
+
+// class map
+
+// template <class... Args>
+// pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
+// template <class... Args>
+// pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
+// template <class... Args>
+// iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
+// template <class... Args>
+// iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
+
+#include <__config>
+#include <map>
+#include <cassert>
+#include <tuple>
+
+class Moveable
+{
+ Moveable(const Moveable&);
+ Moveable& operator=(const Moveable&);
+
+ int int_;
+ double double_;
+public:
+ Moveable() : int_(0), double_(0) {}
+ Moveable(int i, double d) : int_(i), double_(d) {}
+ Moveable(Moveable&& x)
+ : int_(x.int_), double_(x.double_)
+ {x.int_ = -1; x.double_ = -1;}
+ Moveable& operator=(Moveable&& x)
+ {int_ = x.int_; x.int_ = -1;
+ double_ = x.double_; x.double_ = -1;
+ return *this;
+ }
+
+ bool operator==(const Moveable& x) const
+ {return int_ == x.int_ && double_ == x.double_;}
+ bool operator<(const Moveable& x) const
+ {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
+
+ int get() const {return int_;}
+ bool moved() const {return int_ == -1;}
+};
+
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+ { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
+ typedef std::map<int, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace (i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+
+ Moveable mv1(3, 3.0);
+ for (int i=0; i < 20; i += 2)
+ {
+ r = m.try_emplace(i, std::move(mv1));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(!mv1.moved()); // was not moved from
+ assert(r.first->first == i); // key
+ }
+
+ r = m.try_emplace(-1, std::move(mv1));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv1.moved()); // was moved from
+ assert(r.first->first == -1); // key
+ assert(r.first->second.get() == 3); // value
+
+ Moveable mv2(5, 3.0);
+ r = m.try_emplace(5, std::move(mv2));
+ assert(m.size() == 12);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(r.first->first == 5); // key
+ assert(r.first->second.get() == 5); // value
+
+ Moveable mv3(-1, 3.0);
+ r = m.try_emplace(117, std::move(mv2));
+ assert(m.size() == 13);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(r.first->first == 117); // key
+ assert(r.first->second.get() == -1); // value
+ }
+
+ { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
+ typedef std::map<Moveable, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.try_emplace(std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(!mv1.moved()); // was not moved from
+ assert(!mvkey1.moved()); // was not moved from
+ assert(r.first->first == mvkey1); // key
+
+ Moveable mvkey2(3, 3.0);
+ r = m.try_emplace(std::move(mvkey2), std::move(mv1));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv1.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r.first->first.get() == 3); // key
+ assert(r.first->second.get() == 4); // value
+ }
+
+ { // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
+ typedef std::map<int, Moveable> M;
+ M m;
+ M::iterator r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.try_emplace ( i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+ M::const_iterator it = m.find(2);
+
+ Moveable mv1(3, 3.0);
+ for (int i=0; i < 20; i += 2)
+ {
+ r = m.try_emplace(it, i, std::move(mv1));
+ assert(m.size() == 10);
+ assert(!mv1.moved()); // was not moved from
+ assert(r->first == i); // key
+ assert(r->second.get() == i); // value
+ }
+
+ r = m.try_emplace(it, 3, std::move(mv1));
+ assert(m.size() == 11);
+ assert(mv1.moved()); // was moved from
+ assert(r->first == 3); // key
+ assert(r->second.get() == 3); // value
+ }
+
+ { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
+ typedef std::map<Moveable, Moveable> M;
+ M m;
+ M::iterator r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+ M::const_iterator it = std::next(m.cbegin());
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.try_emplace(it, std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(!mv1.moved()); // was not moved from
+ assert(!mvkey1.moved()); // was not moved from
+ assert(r->first == mvkey1); // key
+
+ Moveable mvkey2(3, 3.0);
+ r = m.try_emplace(it, std::move(mvkey2), std::move(mv1));
+ assert(m.size() == 11);
+ assert(mv1.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r->first.get() == 3); // key
+ assert(r->second.get() == 4); // value
+ }
+
+#endif // _LIBCPP_HAS_NO_VARIADICS
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/containers/associative/map/map.ops/count.pass.cpp b/test/std/containers/associative/map/map.ops/count.pass.cpp
index 9668055..ae87ae8 100644
--- a/test/std/containers/associative/map/map.ops/count.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/count.pass.cpp
@@ -18,6 +18,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -133,6 +134,25 @@
assert(r == 1);
r = m.count(4);
assert(r == 0);
+
+ r = m.count(C2Int(5));
+ assert(r == 1);
+ r = m.count(C2Int(6));
+ assert(r == 1);
+ r = m.count(C2Int(7));
+ assert(r == 1);
+ r = m.count(C2Int(8));
+ assert(r == 1);
+ r = m.count(C2Int(9));
+ assert(r == 1);
+ r = m.count(C2Int(10));
+ assert(r == 1);
+ r = m.count(C2Int(11));
+ assert(r == 1);
+ r = m.count(C2Int(12));
+ assert(r == 1);
+ r = m.count(C2Int(4));
+ assert(r == 0);
}
{
diff --git a/test/std/containers/associative/map/map.ops/count0.pass.cpp b/test/std/containers/associative/map/map.ops/count0.pass.cpp
new file mode 100644
index 0000000..ce54936
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/count0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::map<int, double, transparent_less> M;
+
+ M().count(C2Int{5});
+}
diff --git a/test/std/containers/associative/map/map.ops/count1.fail.cpp b/test/std/containers/associative/map/map.ops/count1.fail.cpp
new file mode 100644
index 0000000..9c15059
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/count1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_no_type> M;
+
+ M().count(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/count2.fail.cpp b/test/std/containers/associative/map/map.ops/count2.fail.cpp
new file mode 100644
index 0000000..7aa1553
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/count2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_private> M;
+
+ M().count(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/count3.fail.cpp b/test/std/containers/associative/map/map.ops/count3.fail.cpp
new file mode 100644
index 0000000..7e7bb8f
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/count3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_not_a_type> M;
+
+ M().count(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/equal_range.pass.cpp b/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
index dff751c..a71149a 100644
--- a/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -365,6 +366,58 @@
r = m.equal_range(20);
assert(r.first == next(m.begin(), 8));
assert(r.second == next(m.begin(), 8));
+
+ r = m.equal_range(C2Int(5));
+ assert(r.first == next(m.begin(), 0));
+ assert(r.second == next(m.begin(), 1));
+ r = m.equal_range(C2Int(7));
+ assert(r.first == next(m.begin(), 1));
+ assert(r.second == next(m.begin(), 2));
+ r = m.equal_range(C2Int(9));
+ assert(r.first == next(m.begin(), 2));
+ assert(r.second == next(m.begin(), 3));
+ r = m.equal_range(C2Int(11));
+ assert(r.first == next(m.begin(), 3));
+ assert(r.second == next(m.begin(), 4));
+ r = m.equal_range(C2Int(13));
+ assert(r.first == next(m.begin(), 4));
+ assert(r.second == next(m.begin(), 5));
+ r = m.equal_range(C2Int(15));
+ assert(r.first == next(m.begin(), 5));
+ assert(r.second == next(m.begin(), 6));
+ r = m.equal_range(C2Int(17));
+ assert(r.first == next(m.begin(), 6));
+ assert(r.second == next(m.begin(), 7));
+ r = m.equal_range(C2Int(19));
+ assert(r.first == next(m.begin(), 7));
+ assert(r.second == next(m.begin(), 8));
+ r = m.equal_range(C2Int(4));
+ assert(r.first == next(m.begin(), 0));
+ assert(r.second == next(m.begin(), 0));
+ r = m.equal_range(C2Int(6));
+ assert(r.first == next(m.begin(), 1));
+ assert(r.second == next(m.begin(), 1));
+ r = m.equal_range(C2Int(8));
+ assert(r.first == next(m.begin(), 2));
+ assert(r.second == next(m.begin(), 2));
+ r = m.equal_range(C2Int(10));
+ assert(r.first == next(m.begin(), 3));
+ assert(r.second == next(m.begin(), 3));
+ r = m.equal_range(C2Int(12));
+ assert(r.first == next(m.begin(), 4));
+ assert(r.second == next(m.begin(), 4));
+ r = m.equal_range(C2Int(14));
+ assert(r.first == next(m.begin(), 5));
+ assert(r.second == next(m.begin(), 5));
+ r = m.equal_range(C2Int(16));
+ assert(r.first == next(m.begin(), 6));
+ assert(r.second == next(m.begin(), 6));
+ r = m.equal_range(C2Int(18));
+ assert(r.first == next(m.begin(), 7));
+ assert(r.second == next(m.begin(), 7));
+ r = m.equal_range(C2Int(20));
+ assert(r.first == next(m.begin(), 8));
+ assert(r.second == next(m.begin(), 8));
}
{
typedef PrivateConstructor PC;
diff --git a/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp b/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
new file mode 100644
index 0000000..c95c3df
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::map<int, double, transparent_less> M;
+
+ M().equal_range(C2Int{5});
+}
diff --git a/test/std/containers/associative/map/map.ops/equal_range1.fail.cpp b/test/std/containers/associative/map/map.ops/equal_range1.fail.cpp
new file mode 100644
index 0000000..8f0da08
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/equal_range1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_no_type> M;
+
+ M().equal_range(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/equal_range2.fail.cpp b/test/std/containers/associative/map/map.ops/equal_range2.fail.cpp
new file mode 100644
index 0000000..e73122d
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/equal_range2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_private> M;
+
+ M().equal_range(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/equal_range3.fail.cpp b/test/std/containers/associative/map/map.ops/equal_range3.fail.cpp
new file mode 100644
index 0000000..bb72e9e
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/equal_range3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_not_a_type> M;
+
+ M().equal_range(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/find.pass.cpp b/test/std/containers/associative/map/map.ops/find.pass.cpp
index a757844..17463b6 100644
--- a/test/std/containers/associative/map/map.ops/find.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/find.pass.cpp
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -200,6 +201,25 @@
assert(r == next(m.begin(), 7));
r = m.find(4);
assert(r == next(m.begin(), 8));
+
+ r = m.find(C2Int(5));
+ assert(r == m.begin());
+ r = m.find(C2Int(6));
+ assert(r == next(m.begin()));
+ r = m.find(C2Int(7));
+ assert(r == next(m.begin(), 2));
+ r = m.find(C2Int(8));
+ assert(r == next(m.begin(), 3));
+ r = m.find(C2Int(9));
+ assert(r == next(m.begin(), 4));
+ r = m.find(C2Int(10));
+ assert(r == next(m.begin(), 5));
+ r = m.find(C2Int(11));
+ assert(r == next(m.begin(), 6));
+ r = m.find(C2Int(12));
+ assert(r == next(m.begin(), 7));
+ r = m.find(C2Int(4));
+ assert(r == next(m.begin(), 8));
}
{
diff --git a/test/std/containers/associative/map/map.ops/find0.pass.cpp b/test/std/containers/associative/map/map.ops/find0.pass.cpp
new file mode 100644
index 0000000..5f310b0
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/find0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::map<int, double, transparent_less> M;
+
+ M().find(C2Int{5});
+}
diff --git a/test/std/containers/associative/map/map.ops/find1.fail.cpp b/test/std/containers/associative/map/map.ops/find1.fail.cpp
new file mode 100644
index 0000000..c33b5a9
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/find1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_no_type> M;
+
+ M().find(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/find2.fail.cpp b/test/std/containers/associative/map/map.ops/find2.fail.cpp
new file mode 100644
index 0000000..40bf323
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/find2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_private> M;
+
+ M().find(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/find3.fail.cpp b/test/std/containers/associative/map/map.ops/find3.fail.cpp
new file mode 100644
index 0000000..9526c0e
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/find3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_not_a_type> M;
+
+ M().find(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp b/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
index 87b84ee..3cbfbf7 100644
--- a/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
+++ b/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -280,6 +281,41 @@
assert(r == next(m.begin(), 7));
r = m.lower_bound(20);
assert(r == next(m.begin(), 8));
+
+ r = m.lower_bound(C2Int(5));
+ assert(r == m.begin());
+ r = m.lower_bound(C2Int(7));
+ assert(r == next(m.begin()));
+ r = m.lower_bound(C2Int(9));
+ assert(r == next(m.begin(), 2));
+ r = m.lower_bound(C2Int(11));
+ assert(r == next(m.begin(), 3));
+ r = m.lower_bound(C2Int(13));
+ assert(r == next(m.begin(), 4));
+ r = m.lower_bound(C2Int(15));
+ assert(r == next(m.begin(), 5));
+ r = m.lower_bound(C2Int(17));
+ assert(r == next(m.begin(), 6));
+ r = m.lower_bound(C2Int(19));
+ assert(r == next(m.begin(), 7));
+ r = m.lower_bound(C2Int(4));
+ assert(r == next(m.begin(), 0));
+ r = m.lower_bound(C2Int(6));
+ assert(r == next(m.begin(), 1));
+ r = m.lower_bound(C2Int(8));
+ assert(r == next(m.begin(), 2));
+ r = m.lower_bound(C2Int(10));
+ assert(r == next(m.begin(), 3));
+ r = m.lower_bound(C2Int(12));
+ assert(r == next(m.begin(), 4));
+ r = m.lower_bound(C2Int(14));
+ assert(r == next(m.begin(), 5));
+ r = m.lower_bound(C2Int(16));
+ assert(r == next(m.begin(), 6));
+ r = m.lower_bound(C2Int(18));
+ assert(r == next(m.begin(), 7));
+ r = m.lower_bound(C2Int(20));
+ assert(r == next(m.begin(), 8));
}
{
diff --git a/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp b/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
new file mode 100644
index 0000000..2fc095a
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class map
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::map<int, double, transparent_less> M;
+
+ M().lower_bound(C2Int{5});
+}
diff --git a/test/std/containers/associative/map/map.ops/lower_bound1.fail.cpp b/test/std/containers/associative/map/map.ops/lower_bound1.fail.cpp
new file mode 100644
index 0000000..a4a986c
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/lower_bound1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_no_type> M;
+
+ M().lower_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/map/map.ops/lower_bound2.fail.cpp b/test/std/containers/associative/map/map.ops/lower_bound2.fail.cpp
new file mode 100644
index 0000000..3f6380e
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/lower_bound2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_private> M;
+
+ M().lower_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/map/map.ops/lower_bound3.fail.cpp b/test/std/containers/associative/map/map.ops/lower_bound3.fail.cpp
new file mode 100644
index 0000000..18f2c7b
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/lower_bound3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_not_a_type> M;
+
+ M().lower_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp b/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
new file mode 100644
index 0000000..c58e55f
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class map
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::map<int, double, transparent_less> M;
+
+ M().upper_bound(C2Int{5});
+}
diff --git a/test/std/containers/associative/map/map.ops/upper_bound1.fail.cpp b/test/std/containers/associative/map/map.ops/upper_bound1.fail.cpp
new file mode 100644
index 0000000..4647681
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/upper_bound1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_no_type> M;
+
+ M().upper_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/map/map.ops/upper_bound2.fail.cpp b/test/std/containers/associative/map/map.ops/upper_bound2.fail.cpp
new file mode 100644
index 0000000..11852fe
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/upper_bound2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_private> M;
+
+ M().upper_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/map/map.ops/upper_bound3.fail.cpp b/test/std/containers/associative/map/map.ops/upper_bound3.fail.cpp
new file mode 100644
index 0000000..9cddeb8
--- /dev/null
+++ b/test/std/containers/associative/map/map.ops/upper_bound3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::map<int, double, transparent_less_not_a_type> M;
+
+ M().upper_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp b/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
index c238ed2..4598e99 100644
--- a/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(map& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
// This tests a conforming extension
@@ -33,6 +37,60 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -56,5 +114,35 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for comp
+ typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for comp
+ typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for comp
+ typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for comp
+ typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for comp
+ typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp b/test/std/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp
index d91295b..ba55351 100644
--- a/test/std/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.modifiers/erase_iter.pass.cpp
@@ -18,6 +18,14 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator<(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+
int main()
{
{
@@ -276,4 +284,18 @@
assert(i == m.end());
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::multimap<T, int> C;
+ typedef C::iterator I;
+
+ C c;
+ T a{0};
+ I it = c.find(a);
+ if (it != c.end())
+ c.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/associative/multimap/multimap.ops/count.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/count.pass.cpp
index 2f172d1..c666c29 100644
--- a/test/std/containers/associative/multimap/multimap.ops/count.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/count.pass.cpp
@@ -18,6 +18,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -122,6 +123,21 @@
assert(r == 3);
r = m.count(10);
assert(r == 0);
+
+ r = m.count(C2Int(4));
+ assert(r == 0);
+ r = m.count(C2Int(5));
+ assert(r == 3);
+ r = m.count(C2Int(6));
+ assert(r == 0);
+ r = m.count(C2Int(7));
+ assert(r == 3);
+ r = m.count(C2Int(8));
+ assert(r == 0);
+ r = m.count(C2Int(9));
+ assert(r == 3);
+ r = m.count(C2Int(10));
+ assert(r == 0);
}
{
diff --git a/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
new file mode 100644
index 0000000..7da13bb
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/count0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less> M;
+
+ M().count(C2Int{5});
+}
diff --git a/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp
new file mode 100644
index 0000000..f30d1bf
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/count1.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less_no_type> M;
+
+ M().count(C2Int{5});
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp
new file mode 100644
index 0000000..ffb7eb6
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/count2.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less_private> M;
+
+ M().count(C2Int{5});
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp
new file mode 100644
index 0000000..4bb9d14
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/count3.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less_not_a_type> M;
+
+ M().count(C2Int{5});
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/equal_range.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/equal_range.pass.cpp
index a408796..5a07104 100644
--- a/test/std/containers/associative/multimap/multimap.ops/equal_range.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/equal_range.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// <map>
+// <multimap>
// class multimap
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -219,6 +220,28 @@
r = m.equal_range(10);
assert(r.first == m.end());
assert(r.second == m.end());
+
+ r = m.equal_range(C2Int(4));
+ assert(r.first == m.begin());
+ assert(r.second == m.begin());
+ r = m.equal_range(C2Int(5));
+ assert(r.first == m.begin());
+ assert(r.second == next(m.begin(), 3));
+ r = m.equal_range(C2Int(6));
+ assert(r.first == next(m.begin(), 3));
+ assert(r.second == next(m.begin(), 3));
+ r = m.equal_range(C2Int(7));
+ assert(r.first == next(m.begin(), 3));
+ assert(r.second == next(m.begin(), 6));
+ r = m.equal_range(C2Int(8));
+ assert(r.first == next(m.begin(), 6));
+ assert(r.second == next(m.begin(), 6));
+ r = m.equal_range(C2Int(9));
+ assert(r.first == next(m.begin(), 6));
+ assert(r.second == next(m.begin(), 9));
+ r = m.equal_range(C2Int(10));
+ assert(r.first == m.end());
+ assert(r.second == m.end());
}
{
diff --git a/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
new file mode 100644
index 0000000..c0f0746
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/equal_range0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less> M;
+
+ M().equal_range(C2Int{5});
+}
diff --git a/test/std/containers/associative/multimap/multimap.ops/equal_range1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/equal_range1.fail.cpp
new file mode 100644
index 0000000..f022e94
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/equal_range1.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less_no_type> M;
+
+ M().equal_range(C2Int{5});
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/equal_range2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/equal_range2.fail.cpp
new file mode 100644
index 0000000..695e717
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/equal_range2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_private> M;
+
+ M().equal_range(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/equal_range3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/equal_range3.fail.cpp
new file mode 100644
index 0000000..59c2855
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/equal_range3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_not_a_type> M;
+
+ M().equal_range(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp
index fb5afa2..a60e42c 100644
--- a/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/find.pass.cpp
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -174,6 +175,19 @@
assert(r == next(m.begin(), 6));
r = m.find(10);
assert(r == m.end());
+
+ r = m.find(C2Int(5));
+ assert(r == m.begin());
+ r = m.find(C2Int(6));
+ assert(r == m.end());
+ r = m.find(C2Int(7));
+ assert(r == next(m.begin(), 3));
+ r = m.find(C2Int(8));
+ assert(r == m.end());
+ r = m.find(C2Int(9));
+ assert(r == next(m.begin(), 6));
+ r = m.find(C2Int(10));
+ assert(r == m.end());
}
{
diff --git a/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
new file mode 100644
index 0000000..4f33698
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/find0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less> M;
+
+ M().find(C2Int{5});
+}
diff --git a/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp
new file mode 100644
index 0000000..e1eef03
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/find1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_no_type> M;
+
+ M().find(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp
new file mode 100644
index 0000000..4c03f58
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/find2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_private> M;
+
+ M().find(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp
new file mode 100644
index 0000000..f10bc60
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/find3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator find(const key_type& k);
+// const_iterator find(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_not_a_type> M;
+
+ M().find(C2Int{5});
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/std/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp
index 49cf6de..38b9318 100644
--- a/test/std/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound.pass.cpp
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -183,6 +184,21 @@
assert(r == next(m.begin(), 6));
r = m.lower_bound(10);
assert(r == m.end());
+
+ r = m.lower_bound(C2Int(4));
+ assert(r == m.begin());
+ r = m.lower_bound(C2Int(5));
+ assert(r == m.begin());
+ r = m.lower_bound(C2Int(6));
+ assert(r == next(m.begin(), 3));
+ r = m.lower_bound(C2Int(7));
+ assert(r == next(m.begin(), 3));
+ r = m.lower_bound(C2Int(8));
+ assert(r == next(m.begin(), 6));
+ r = m.lower_bound(C2Int(9));
+ assert(r == next(m.begin(), 6));
+ r = m.lower_bound(C2Int(10));
+ assert(r == m.end());
}
{
diff --git a/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
new file mode 100644
index 0000000..c5271f6
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class multimap
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less> M;
+
+ M().lower_bound(C2Int{5});
+}
diff --git a/test/std/containers/associative/multimap/multimap.ops/lower_bound1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/lower_bound1.fail.cpp
new file mode 100644
index 0000000..b452be8
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_no_type> M;
+
+ M().lower_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/multimap/multimap.ops/lower_bound2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/lower_bound2.fail.cpp
new file mode 100644
index 0000000..a2ba302
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_private> M;
+
+ M().lower_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/multimap/multimap.ops/lower_bound3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/lower_bound3.fail.cpp
new file mode 100644
index 0000000..50d9fca
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/lower_bound3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator lower_bound(const key_type& k);
+// const_iterator lower_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_not_a_type> M;
+
+ M().lower_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp
index 1920647..7c647a9 100644
--- a/test/std/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound.pass.cpp
@@ -19,6 +19,7 @@
#include "min_allocator.h"
#include "private_constructor.hpp"
+#include "is_transparent.h"
int main()
{
@@ -183,6 +184,20 @@
assert(r == next(m.begin(), 9));
r = m.upper_bound(10);
assert(r == m.end());
+
+ r = m.upper_bound(C2Int(4));
+ assert(r == m.begin());
+ r = m.upper_bound(C2Int(5));
+ assert(r == next(m.begin(), 3));
+ r = m.upper_bound(C2Int(6));
+ assert(r == next(m.begin(), 3));
+ r = m.upper_bound(C2Int(7));
+ assert(r == next(m.begin(), 6));
+ r = m.upper_bound(C2Int(8));
+ assert(r == next(m.begin(), 6));
+ r = m.upper_bound(C2Int(9));
+ assert(r == next(m.begin(), 9));
+ r = m.upper_bound(C2Int(10));
}
{
diff --git a/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp b/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
new file mode 100644
index 0000000..322c6f5
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound0.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// XFAIL: c++03, c++11
+
+// <map>
+
+// class multimap
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+int main()
+{
+ typedef std::multimap<int, double, transparent_less> M;
+
+ M().upper_bound(C2Int{5});
+}
diff --git a/test/std/containers/associative/multimap/multimap.ops/upper_bound1.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/upper_bound1.fail.cpp
new file mode 100644
index 0000000..bb78ad6
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound1.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_no_type> M;
+
+ M().upper_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/multimap/multimap.ops/upper_bound2.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/upper_bound2.fail.cpp
new file mode 100644
index 0000000..a79d593
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound2.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_private> M;
+
+ M().upper_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/multimap/multimap.ops/upper_bound3.fail.cpp b/test/std/containers/associative/multimap/multimap.ops/upper_bound3.fail.cpp
new file mode 100644
index 0000000..1c1dc74
--- /dev/null
+++ b/test/std/containers/associative/multimap/multimap.ops/upper_bound3.fail.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class multimap
+
+// iterator upper_bound(const key_type& k);
+// const_iterator upper_bound(const key_type& k) const;
+//
+// The member function templates find, count, lower_bound, upper_bound, and
+// equal_range shall not participate in overload resolution unless the
+// qualified-id Compare::is_transparent is valid and denotes a type
+
+
+#include <map>
+#include <cassert>
+
+#include "is_transparent.h"
+
+#if _LIBCPP_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+int main()
+{
+ {
+ typedef std::multimap<int, double, transparent_less_not_a_type> M;
+
+ M().upper_bound(C2Int{5});
+ }
+}
+#endif
diff --git a/test/std/containers/associative/multimap/multimap.special/swap_noexcept.pass.cpp b/test/std/containers/associative/multimap/multimap.special/swap_noexcept.pass.cpp
index 07882a4..1013c62 100644
--- a/test/std/containers/associative/multimap/multimap.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/associative/multimap/multimap.special/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(multimap& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
// This tests a conforming extension
@@ -33,6 +37,60 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -56,5 +114,35 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for comp
+ typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for comp
+ typedef std::multimap<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for comp
+ typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for comp
+ typedef std::multimap<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for comp
+ typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/associative/multimap/scary.pass.cpp b/test/std/containers/associative/multimap/scary.pass.cpp
index b99d9bc..e6dc5aa 100644
--- a/test/std/containers/associative/multimap/scary.pass.cpp
+++ b/test/std/containers/associative/multimap/scary.pass.cpp
@@ -21,4 +21,5 @@
typedef std::multimap<int, int> M2;
M2::iterator i;
M1::iterator j = i;
+ ((void)j);
}
diff --git a/test/std/containers/associative/multiset/erase_iter.pass.cpp b/test/std/containers/associative/multiset/erase_iter.pass.cpp
index b665666..1d41540 100644
--- a/test/std/containers/associative/multiset/erase_iter.pass.cpp
+++ b/test/std/containers/associative/multiset/erase_iter.pass.cpp
@@ -18,6 +18,14 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator<(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+
int main()
{
{
@@ -178,4 +186,18 @@
assert(i == m.end());
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::multiset<T> C;
+ typedef C::iterator I;
+
+ C c;
+ T a{0};
+ I it = c.find(a);
+ if (it != c.end())
+ c.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/associative/multiset/multiset.special/swap_noexcept.pass.cpp b/test/std/containers/associative/multiset/multiset.special/swap_noexcept.pass.cpp
index cd5be79..8e2c67c 100644
--- a/test/std/containers/associative/multiset/multiset.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/associative/multiset/multiset.special/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(multiset& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
// This tests a conforming extension
@@ -33,6 +37,60 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -56,5 +114,35 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for comp
+ typedef std::multiset<MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for comp
+ typedef std::multiset<MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for comp
+ typedef std::multiset<MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for comp
+ typedef std::multiset<MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for comp
+ typedef std::multiset<MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/associative/multiset/scary.pass.cpp b/test/std/containers/associative/multiset/scary.pass.cpp
index f5ee327..bc4328b 100644
--- a/test/std/containers/associative/multiset/scary.pass.cpp
+++ b/test/std/containers/associative/multiset/scary.pass.cpp
@@ -21,4 +21,5 @@
typedef std::multiset<int> M2;
M2::iterator i;
M1::iterator j = i;
+ ((void)j);
}
diff --git a/test/std/containers/associative/set/erase_iter.pass.cpp b/test/std/containers/associative/set/erase_iter.pass.cpp
index 21666c3..36828be 100644
--- a/test/std/containers/associative/set/erase_iter.pass.cpp
+++ b/test/std/containers/associative/set/erase_iter.pass.cpp
@@ -18,6 +18,14 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator<(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+
int main()
{
{
@@ -178,4 +186,18 @@
assert(i == m.end());
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::set<T> C;
+ typedef C::iterator I;
+
+ C c;
+ T a{0};
+ I it = c.find(a);
+ if (it != c.end())
+ c.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/associative/set/set.special/swap_noexcept.pass.cpp b/test/std/containers/associative/set/set.special/swap_noexcept.pass.cpp
index a478b25..3ec6976 100644
--- a/test/std/containers/associative/set/set.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/associative/set/set.special/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(set& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
// This tests a conforming extension
@@ -33,6 +37,60 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -56,5 +114,35 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for comp
+ typedef std::set<MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for comp
+ typedef std::set<MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for comp
+ typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for comp
+ typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for comp
+ typedef std::set<MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp b/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp
index b9775ee..34db59d 100644
--- a/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp
+++ b/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.data/data.pass.cpp b/test/std/containers/sequences/array/array.data/data.pass.cpp
index 08e4fd3..80b7d06 100644
--- a/test/std/containers/sequences/array/array.data/data.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.data/data_const.pass.cpp b/test/std/containers/sequences/array/array.data/data_const.pass.cpp
index 8eb9762..1c9abdd 100644
--- a/test/std/containers/sequences/array/array.data/data_const.pass.cpp
+++ b/test/std/containers/sequences/array/array.data/data_const.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.fill/fill.pass.cpp b/test/std/containers/sequences/array/array.fill/fill.pass.cpp
index 675f495..f98dbbd 100644
--- a/test/std/containers/sequences/array/array.fill/fill.pass.cpp
+++ b/test/std/containers/sequences/array/array.fill/fill.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.size/size.pass.cpp b/test/std/containers/sequences/array/array.size/size.pass.cpp
index fe5a0d5..89b893a 100644
--- a/test/std/containers/sequences/array/array.size/size.pass.cpp
+++ b/test/std/containers/sequences/array/array.size/size.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.special/swap.pass.cpp b/test/std/containers/sequences/array/array.special/swap.pass.cpp
index 08e4377..82ce904 100644
--- a/test/std/containers/sequences/array/array.special/swap.pass.cpp
+++ b/test/std/containers/sequences/array/array.special/swap.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.swap/swap.pass.cpp b/test/std/containers/sequences/array/array.swap/swap.pass.cpp
index c7a4cb8..22bf657 100644
--- a/test/std/containers/sequences/array/array.swap/swap.pass.cpp
+++ b/test/std/containers/sequences/array/array.swap/swap.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
{
diff --git a/test/std/containers/sequences/array/array.tuple/get.fail.cpp b/test/std/containers/sequences/array/array.tuple/get.fail.cpp
index 4f4fbcf..6b2385d 100644
--- a/test/std/containers/sequences/array/array.tuple/get.fail.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get.fail.cpp
@@ -11,15 +11,28 @@
// template <size_t I, class T, size_t N> T& get(array<T, N>& a);
+// Prevent -Warray-bounds from issuing a diagnostic when testing with clang verify.
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Warray-bounds"
+#endif
+
#include <array>
#include <cassert>
+#include "test_macros.h"
+#include "../suppress_array_warnings.h"
+
int main()
{
{
typedef double T;
typedef std::array<T, 3> C;
C c = {1, 2, 3.5};
- std::get<3>(c) = 5.5; // Can't get element 3!
+ std::get<3>(c) = 5.5; // expected-note {{requested here}}
+#if TEST_STD_VER >= 11
+ // expected-error@array:* {{static_assert failed "Index out of bounds in std::get<> (std::array)"}}
+#else
+ // expected-error@array:* {{implicit instantiation of undefined template '__static_assert_test<false>'}}
+#endif
}
}
diff --git a/test/std/containers/sequences/array/array.tuple/get.pass.cpp b/test/std/containers/sequences/array/array.tuple/get.pass.cpp
index d9e242c..c455707 100644
--- a/test/std/containers/sequences/array/array.tuple/get.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get.pass.cpp
@@ -14,12 +14,17 @@
#include <array>
#include <cassert>
-#if __cplusplus > 201103L
+#include "test_macros.h"
+
+#include "../suppress_array_warnings.h"
+
+
+#if TEST_STD_VER > 11
struct S {
std::array<int, 3> a;
int k;
constexpr S() : a{1,2,3}, k(std::get<2>(a)) {}
- };
+};
constexpr std::array<int, 2> getArr () { return { 3, 4 }; }
#endif
@@ -35,7 +40,7 @@
assert(c[1] == 5.5);
assert(c[2] == 3.5);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef double T;
typedef std::array<T, 3> C;
diff --git a/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp b/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
index 1cbdfa4..ddc2ab2 100644
--- a/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
@@ -14,6 +14,10 @@
#include <array>
#include <cassert>
+#include "test_macros.h"
+
+#include "../suppress_array_warnings.h"
+
int main()
{
{
@@ -24,7 +28,7 @@
assert(std::get<1>(c) == 2);
assert(std::get<2>(c) == 3.5);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef double T;
typedef std::array<T, 3> C;
diff --git a/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp b/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
index 8eec3ce..412c7c7 100644
--- a/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
@@ -11,14 +11,18 @@
// template <size_t I, class T, size_t N> T&& get(array<T, N>&& a);
+// UNSUPPORTED: c++98, c++03
+
#include <array>
#include <memory>
#include <utility>
#include <cassert>
+#include "../suppress_array_warnings.h"
+
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
{
typedef std::unique_ptr<double> T;
typedef std::array<T, 1> C;
@@ -26,5 +30,4 @@
T t = std::get<0>(std::move(c));
assert(*t == 3.5);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp b/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
index cd1dad6..91d6b4e 100644
--- a/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/tuple_element.pass.cpp
@@ -14,20 +14,41 @@
#include <array>
#include <type_traits>
-int main()
+template <class T>
+void test()
{
{
- typedef double T;
- typedef std::array<T, 3> C;
- static_assert((std::is_same<std::tuple_element<0, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<1, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<2, C>::type, T>::value), "");
+ typedef T Exp;
+ typedef std::array<T, 3> C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
}
{
- typedef int T;
- typedef std::array<T, 3> C;
- static_assert((std::is_same<std::tuple_element<0, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<1, C>::type, T>::value), "");
- static_assert((std::is_same<std::tuple_element<2, C>::type, T>::value), "");
+ typedef T const Exp;
+ typedef std::array<T, 3> const C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
}
+ {
+ typedef T volatile Exp;
+ typedef std::array<T, 3> volatile C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
+ }
+ {
+ typedef T const volatile Exp;
+ typedef std::array<T, 3> const volatile C;
+ static_assert((std::is_same<typename std::tuple_element<0, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, C>::type, Exp>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<2, C>::type, Exp>::value), "");
+ }
+}
+
+int main()
+{
+ test<double>();
+ test<int>();
}
diff --git a/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp b/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
index 83394b1..1e565d1 100644
--- a/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
+++ b/test/std/containers/sequences/array/array.tuple/tuple_size.pass.cpp
@@ -13,16 +13,30 @@
#include <array>
-int main()
+template <class T, std::size_t N>
+void test()
{
{
- typedef double T;
- typedef std::array<T, 3> C;
- static_assert((std::tuple_size<C>::value == 3), "");
+ typedef std::array<T, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
}
{
- typedef double T;
- typedef std::array<T, 0> C;
- static_assert((std::tuple_size<C>::value == 0), "");
+ typedef std::array<T const, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
}
+ {
+ typedef std::array<T volatile, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
+ }
+ {
+ typedef std::array<T const volatile, N> C;
+ static_assert((std::tuple_size<C>::value == N), "");
+ }
+}
+
+int main()
+{
+ test<double, 0>();
+ test<double, 3>();
+ test<double, 5>();
}
diff --git a/test/std/containers/sequences/array/at.pass.cpp b/test/std/containers/sequences/array/at.pass.cpp
index b5cf8a5..c4f7acb 100644
--- a/test/std/containers/sequences/array/at.pass.cpp
+++ b/test/std/containers/sequences/array/at.pass.cpp
@@ -17,6 +17,10 @@
#include <array>
#include <cassert>
+#include "test_macros.h"
+
+#include "suppress_array_warnings.h"
+
int main()
{
{
@@ -27,7 +31,7 @@
assert(r1 == 1);
r1 = 5.5;
assert(c.front() == 5.5);
-
+
C::reference r2 = c.at(2);
assert(r2 == 3.5);
r2 = 7.5;
@@ -50,7 +54,7 @@
catch (const std::out_of_range &) {}
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef double T;
typedef std::array<T, 3> C;
diff --git a/test/std/containers/sequences/array/begin.pass.cpp b/test/std/containers/sequences/array/begin.pass.cpp
index 9cba0d6..a6218ae 100644
--- a/test/std/containers/sequences/array/begin.pass.cpp
+++ b/test/std/containers/sequences/array/begin.pass.cpp
@@ -14,6 +14,8 @@
#include <array>
#include <cassert>
+#include "suppress_array_warnings.h"
+
int main()
{
{
@@ -27,6 +29,4 @@
*i = 5.5;
assert(c[0] == 5.5);
}
- {
- }
}
diff --git a/test/std/containers/sequences/array/contiguous.pass.cpp b/test/std/containers/sequences/array/contiguous.pass.cpp
new file mode 100644
index 0000000..27933b0
--- /dev/null
+++ b/test/std/containers/sequences/array/contiguous.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// An array is a contiguous container
+
+#include <array>
+#include <cassert>
+
+template <class C>
+void test_contiguous ( const C &c )
+{
+ for ( size_t i = 0; i < c.size(); ++i )
+ assert ( *(c.begin() + i) == *(std::addressof(*c.begin()) + i));
+}
+
+int main()
+{
+ {
+ typedef double T;
+ typedef std::array<T, 3> C;
+ test_contiguous (C());
+ }
+}
diff --git a/test/std/containers/sequences/array/front_back.pass.cpp b/test/std/containers/sequences/array/front_back.pass.cpp
index 45a963b..ebe3a18 100644
--- a/test/std/containers/sequences/array/front_back.pass.cpp
+++ b/test/std/containers/sequences/array/front_back.pass.cpp
@@ -17,6 +17,10 @@
#include <array>
#include <cassert>
+#include "test_macros.h"
+
+#include "suppress_array_warnings.h"
+
int main()
{
{
@@ -45,12 +49,12 @@
assert(r2 == 3.5);
}
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
{
typedef double T;
typedef std::array<T, 3> C;
constexpr C c = {1, 2, 3.5};
-
+
constexpr T t1 = c.front();
static_assert (t1 == 1, "");
diff --git a/test/std/containers/sequences/array/indexing.pass.cpp b/test/std/containers/sequences/array/indexing.pass.cpp
index e4dda0d..c550d14 100644
--- a/test/std/containers/sequences/array/indexing.pass.cpp
+++ b/test/std/containers/sequences/array/indexing.pass.cpp
@@ -17,6 +17,10 @@
#include <array>
#include <cassert>
+#include "test_macros.h"
+
+#include "suppress_array_warnings.h"
+
int main()
{
{
@@ -42,13 +46,13 @@
C::const_reference r2 = c[2];
assert(r2 == 3.5);
}
-
-#if _LIBCPP_STD_VER > 11
+
+#if TEST_STD_VER > 11
{
typedef double T;
typedef std::array<T, 3> C;
constexpr C c = {1, 2, 3.5};
-
+
constexpr T t1 = c[0];
static_assert (t1 == 1, "");
diff --git a/test/std/containers/sequences/array/suppress_array_warnings.h b/test/std/containers/sequences/array/suppress_array_warnings.h
new file mode 100644
index 0000000..1dde3d3
--- /dev/null
+++ b/test/std/containers/sequences/array/suppress_array_warnings.h
@@ -0,0 +1,8 @@
+#ifndef SUPPRESS_ARRAY_WARNINGS_H
+#define SUPPRESS_ARRAY_WARNINGS_H
+
+// std::array is explicitly allowed to be initialized with A a = { init-list };.
+// Disable the missing braces warning for this reason.
+#pragma GCC diagnostic ignored "-Wmissing-braces"
+
+#endif // SUPPRESS_ARRAY_WARNINGS
diff --git a/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp b/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
index 522f839..84f04f9 100644
--- a/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.capacity/resize_size.pass.cpp
@@ -14,6 +14,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
@@ -58,7 +59,6 @@
void
testN(int start, int N, int M)
{
- typedef typename C::const_iterator CI;
C c1 = make<C>(N, start);
test(c1, M);
}
@@ -73,7 +73,7 @@
for (int k = 0; k < N; ++k)
testN<std::deque<int> >(rng[i], rng[j], rng[k]);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp b/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
index 9eb514b..2bf2423 100644
--- a/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.capacity/resize_size_value.pass.cpp
@@ -14,6 +14,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
@@ -58,7 +59,6 @@
void
testN(int start, int N, int M)
{
- typedef typename C::const_iterator CI;
C c1 = make<C>(N, start);
test(c1, M, -10);
}
@@ -73,7 +73,7 @@
for (int k = 0; k < N; ++k)
testN<std::deque<int> >(rng[i], rng[j], rng[k]);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp b/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
index fb00069..0cf0387 100644
--- a/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.capacity/shrink_to_fit.pass.cpp
@@ -14,6 +14,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
@@ -51,7 +52,6 @@
void
testN(int start, int N)
{
- typedef typename C::const_iterator CI;
C c1 = make<C>(N, start);
test(c1);
}
@@ -65,7 +65,7 @@
for (int j = 0; j < N; ++j)
testN<std::deque<int> >(rng[i], rng[j]);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
index 51a37cc..6507f58 100644
--- a/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.cons/assign_iter_iter.pass.cpp
@@ -15,6 +15,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "test_iterators.h"
#include "min_allocator.h"
@@ -44,7 +45,6 @@
void
test(C& c1, const C& c2)
{
- std::size_t c1_osize = c1.size();
c1.assign(c2.begin(), c2.end());
assert(distance(c1.begin(), c1.end()) == c1.size());
assert(c1 == c2);
@@ -54,8 +54,6 @@
void
testN(int start, int N, int M)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
C c1 = make<C>(N, start);
C c2 = make<C>(M);
test(c1, c2);
@@ -67,7 +65,6 @@
{
typedef typename C::const_iterator CI;
typedef input_iterator<CI> ICI;
- std::size_t c1_osize = c1.size();
c1.assign(ICI(c2.begin()), ICI(c2.end()));
assert(distance(c1.begin(), c1.end()) == c1.size());
assert(c1 == c2);
@@ -77,8 +74,6 @@
void
testNI(int start, int N, int M)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
C c1 = make<C>(N, start);
C c2 = make<C>(M);
testI(c1, c2);
@@ -95,7 +90,7 @@
testN<std::deque<int> >(rng[i], rng[j], rng[k]);
testNI<std::deque<int> >(1500, 2000, 1000);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp b/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
index 3ab79a0..e00e044 100644
--- a/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.cons/assign_size_value.pass.cpp
@@ -14,6 +14,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "test_iterators.h"
#include "min_allocator.h"
@@ -44,7 +45,6 @@
test(C& c1, int size, int v)
{
typedef typename C::const_iterator CI;
- std::size_t c1_osize = c1.size();
c1.assign(size, v);
assert(c1.size() == size);
assert(distance(c1.begin(), c1.end()) == c1.size());
@@ -56,8 +56,6 @@
void
testN(int start, int N, int M)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
C c1 = make<C>(N, start);
test(c1, M, -10);
}
@@ -72,7 +70,7 @@
for (int k = 0; k < N; ++k)
testN<std::deque<int> >(rng[i], rng[j], rng[k]);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.modifiers/emplace.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/emplace.pass.cpp
index 7a0a251..713f215 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/emplace.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/emplace.pass.cpp
@@ -11,13 +11,14 @@
// template <class... Args> iterator emplace(const_iterator p, Args&&... args);
+// UNSUPPORTED: c++98, c++03
+
#include <deque>
#include <cassert>
#include "../../../Emplaceable.h"
#include "min_allocator.h"
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class C>
C
@@ -45,7 +46,6 @@
void
test(int P, C& c1)
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
std::size_t c1_osize = c1.size();
CI i = c1.emplace(c1.begin() + P, Emplaceable(1, 2.5));
@@ -59,8 +59,6 @@
void
testN(int start, int N)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
for (int i = 0; i <= 3; ++i)
{
if (0 <= i && i <= N)
@@ -87,11 +85,9 @@
}
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
@@ -99,7 +95,6 @@
for (int j = 0; j < N; ++j)
testN<std::deque<Emplaceable> >(rng[i], rng[j]);
}
-#if __cplusplus >= 201103L
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
@@ -107,6 +102,4 @@
for (int j = 0; j < N; ++j)
testN<std::deque<Emplaceable, min_allocator<Emplaceable>> >(rng[i], rng[j]);
}
-#endif
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp
new file mode 100644
index 0000000..49465cd
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// iterator erase(const_iterator f)
+
+// Erasing items from the beginning or the end of a deque shall not invalidate iterators
+// to items that were not erased.
+
+#include <deque>
+#include <cassert>
+
+template <typename C>
+void del_at_start(C c)
+{
+ typename C::iterator first = c.begin();
+ typename C::iterator it1 = first + 1;
+ typename C::iterator it2 = c.end() - 1;
+
+ c.erase (first);
+
+ typename C::iterator it3 = c.begin();
+ typename C::iterator it4 = c.end() - 1;
+ assert( it1 == it3);
+ assert( *it1 == *it3);
+ assert(&*it1 == &*it3);
+ assert( it2 == it4);
+ assert( *it2 == *it4);
+ assert(&*it2 == &*it4);
+}
+
+template <typename C>
+void del_at_end(C c)
+{
+ typename C::iterator first = c.end() - 1;
+ typename C::iterator it1 = c.begin();
+ typename C::iterator it2 = first - 1;
+
+ c.erase (first);
+
+ typename C::iterator it3 = c.begin();
+ typename C::iterator it4 = c.end() - 1;
+ assert( it1 == it3);
+ assert( *it1 == *it3);
+ assert(&*it1 == &*it3);
+ assert( it2 == it4);
+ assert( *it2 == *it4);
+ assert(&*it2 == &*it4);
+}
+
+int main()
+{
+ std::deque<int> queue;
+ for (int i = 0; i < 20; ++i)
+ queue.push_back(i);
+
+ while (queue.size() > 1)
+ {
+ del_at_start(queue);
+ del_at_end(queue);
+ queue.pop_back();
+ }
+}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp
new file mode 100644
index 0000000..c785e26
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// iterator erase(const_iterator f, const_iterator l)
+
+// Erasing items from the beginning or the end of a deque shall not invalidate iterators
+// to items that were not erased.
+
+
+#include <deque>
+#include <cstdint>
+#include <cassert>
+
+template <typename C>
+void del_at_start(C c, size_t num)
+{
+ typename C::iterator first = c.begin();
+ typename C::iterator last = first + num;
+ typename C::iterator it1 = last;
+ typename C::iterator it2 = c.end() - 1;
+
+ c.erase (first, last);
+
+ typename C::iterator it3 = c.begin();
+ typename C::iterator it4 = c.end() - 1;
+ assert( it1 == it3);
+ assert( *it1 == *it3);
+ assert(&*it1 == &*it3);
+ assert( it2 == it4);
+ assert( *it2 == *it4);
+ assert(&*it2 == &*it4);
+}
+
+template <typename C>
+void del_at_end(C c, size_t num)
+{
+ typename C::iterator last = c.end();
+ typename C::iterator first = last - num;
+ typename C::iterator it1 = c.begin();
+ typename C::iterator it2 = first - 1;
+
+ c.erase (first, last);
+
+ typename C::iterator it3 = c.begin();
+ typename C::iterator it4 = c.end() - 1;
+ assert( it1 == it3);
+ assert( *it1 == *it3);
+ assert(&*it1 == &*it3);
+ assert( it2 == it4);
+ assert( *it2 == *it4);
+ assert(&*it2 == &*it4);
+}
+
+
+int main()
+{
+ std::deque<int> queue;
+ for (int i = 0; i < 20; ++i)
+ queue.push_back(i);
+
+ while (queue.size() > 1)
+ {
+ for (size_t i = 1; i < queue.size(); ++i)
+ {
+ del_at_start(queue, i);
+ del_at_end (queue, i);
+ }
+ queue.pop_back();
+ }
+}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp
index ecb95d7..fbe3cb6 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/insert_iter_iter.pass.cpp
@@ -17,6 +17,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "test_iterators.h"
#include "MoveOnly.h"
#include "../../../stack_allocator.h"
@@ -49,7 +50,6 @@
test(int P, const C& c0, const C& c2)
{
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
typedef input_iterator<CI> BCI;
C c1 = c0;
@@ -67,7 +67,6 @@
assert(*i == j);
}
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
typedef forward_iterator<CI> BCI;
C c1 = c0;
@@ -85,7 +84,6 @@
assert(*i == j);
}
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
typedef bidirectional_iterator<CI> BCI;
C c1 = c0;
@@ -108,8 +106,6 @@
void
testN(int start, int N, int M)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
for (int i = 0; i <= 3; ++i)
{
if (0 <= i && i <= N)
@@ -170,7 +166,6 @@
void
testI(int P, C& c1, const C& c2)
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
typedef input_iterator<CI> ICI;
std::size_t c1_osize = c1.size();
@@ -191,8 +186,6 @@
void
testNI(int start, int N, int M)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
for (int i = 0; i <= 3; ++i)
{
if (0 <= i && i <= N)
@@ -244,7 +237,7 @@
void
test_move()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
C c;
typedef typename C::const_iterator CI;
{
@@ -263,7 +256,7 @@
j = 0;
for (CI i = c.begin(); i != c.end(); ++i, ++j)
assert(*i == MoveOnly(j));
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
}
int main()
@@ -276,11 +269,11 @@
for (int k = 0; k < N; ++k)
testN<std::deque<int> >(rng[i], rng[j], rng[k]);
testNI<std::deque<int> >(1500, 2000, 1000);
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
test_move<std::deque<MoveOnly, stack_allocator<MoveOnly, 2000> > >();
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp
index b7e73f2..3c7b0fe 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/insert_rvalue.pass.cpp
@@ -11,13 +11,14 @@
// iterator insert (const_iterator p, value_type&& v);
+// UNSUPPORTED: c++98, c++03
+
#include <deque>
#include <cassert>
#include "MoveOnly.h"
#include "min_allocator.h"
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class C>
C
@@ -45,7 +46,6 @@
void
test(int P, C& c1, int x)
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
std::size_t c1_osize = c1.size();
CI i = c1.insert(c1.begin() + P, MoveOnly(x));
@@ -65,8 +65,6 @@
void
testN(int start, int N)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
for (int i = 0; i <= 3; ++i)
{
if (0 <= i && i <= N)
@@ -93,11 +91,8 @@
}
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
@@ -105,7 +100,6 @@
for (int j = 0; j < N; ++j)
testN<std::deque<MoveOnly> >(rng[i], rng[j]);
}
-#if __cplusplus >= 201103L
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
@@ -113,6 +107,4 @@
for (int j = 0; j < N; ++j)
testN<std::deque<MoveOnly, min_allocator<MoveOnly>> >(rng[i], rng[j]);
}
-#endif
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp
index 2737dfb..0efe3b4 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/insert_size_value.pass.cpp
@@ -16,6 +16,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
@@ -44,7 +45,6 @@
void
test(int P, C& c1, int size, int x)
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
std::size_t c1_osize = c1.size();
CI i = c1.insert(c1.begin() + P, size, x);
@@ -64,8 +64,6 @@
void
testN(int start, int N, int M)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
for (int i = 0; i <= 3; ++i)
{
if (0 <= i && i <= N)
@@ -145,7 +143,7 @@
testN<std::deque<int> >(rng[i], rng[j], rng[k]);
self_reference_test<std::deque<int> >();
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp
index fbbaad4..04c4ca4 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/insert_value.pass.cpp
@@ -14,6 +14,7 @@
#include <deque>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
@@ -42,7 +43,6 @@
void
test(int P, C& c1, int x)
{
- typedef typename C::iterator I;
typedef typename C::const_iterator CI;
std::size_t c1_osize = c1.size();
CI i = c1.insert(c1.begin() + P, x);
@@ -62,8 +62,6 @@
void
testN(int start, int N)
{
- typedef typename C::iterator I;
- typedef typename C::const_iterator CI;
for (int i = 0; i <= 3; ++i)
{
if (0 <= i && i <= N)
@@ -126,7 +124,7 @@
testN<std::deque<int> >(rng[i], rng[j]);
self_reference_test<std::deque<int> >();
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
const int N = sizeof(rng)/sizeof(rng[0]);
diff --git a/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp
new file mode 100644
index 0000000..1d84f73
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// void pop_back()
+
+// Erasing items from the beginning or the end of a deque shall not invalidate iterators
+// to items that were not erased.
+
+#include <deque>
+#include <cassert>
+
+template <typename C>
+void test(C c)
+{
+ typename C::iterator it1 = c.begin();
+ typename C::iterator it2 = c.end() - 2;
+
+ c.pop_back();
+
+ typename C::iterator it3 = c.begin();
+ typename C::iterator it4 = c.end() - 1;
+ assert( it1 == it3);
+ assert( *it1 == *it3);
+ assert(&*it1 == &*it3);
+ assert( it2 == it4);
+ assert( *it2 == *it4);
+ assert(&*it2 == &*it4);
+}
+
+int main()
+{
+ std::deque<int> queue;
+ for (int i = 0; i < 20; ++i)
+ queue.push_back(i);
+
+ while (queue.size() > 1)
+ {
+ test(queue);
+ queue.pop_back();
+ }
+}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp
new file mode 100644
index 0000000..78317f3
--- /dev/null
+++ b/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// void pop_front()
+
+// Erasing items from the beginning or the end of a deque shall not invalidate iterators
+// to items that were not erased.
+
+#include <deque>
+#include <cassert>
+
+template <typename C>
+void test(C c)
+{
+ typename C::iterator it1 = c.begin() + 1;
+ typename C::iterator it2 = c.end() - 1;
+
+ c.pop_front();
+
+ typename C::iterator it3 = c.begin();
+ typename C::iterator it4 = c.end() - 1;
+ assert( it1 == it3);
+ assert( *it1 == *it3);
+ assert(&*it1 == &*it3);
+ assert( it2 == it4);
+ assert( *it2 == *it4);
+ assert(&*it2 == &*it4);
+}
+
+int main()
+{
+ std::deque<int> queue;
+ for (int i = 0; i < 20; ++i)
+ queue.push_back(i);
+
+ while (queue.size() > 1)
+ {
+ test(queue);
+ queue.pop_back();
+ }
+}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
index 3e62879..8ad6b53 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/push_back_exception_safety.pass.cpp
@@ -12,12 +12,12 @@
// void push_back(const value_type& x);
#include <deque>
+#include "test_allocator.h"
#include <cassert>
// Flag that makes the copy constructor for CMyClass throw an exception
static bool gCopyConstructorShouldThow = false;
-
class CMyClass {
public: CMyClass(int tag);
public: CMyClass(const CMyClass& iOther);
@@ -25,6 +25,7 @@
bool equal(const CMyClass &rhs) const
{ return fTag == rhs.fTag && fMagicValue == rhs.fMagicValue; }
+
private:
int fMagicValue;
int fTag;
@@ -66,6 +67,7 @@
int main()
{
CMyClass instance(42);
+ {
std::deque<CMyClass> vec;
vec.push_back(instance);
@@ -74,8 +76,26 @@
gCopyConstructorShouldThow = true;
try {
vec.push_back(instance);
+ assert(false);
+ }
+ catch (...) {
+ gCopyConstructorShouldThow = false;
+ assert(vec==vec2);
+ }
+ }
+
+ {
+ typedef std::deque<CMyClass, test_allocator<CMyClass> > C;
+ C vec;
+ C vec2(vec);
+
+ C::allocator_type::throw_after = 1;
+ try {
+ vec.push_back(instance);
+ assert(false);
}
catch (...) {
assert(vec==vec2);
}
+ }
}
diff --git a/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp b/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
index 6ae06db..e01b2a2 100644
--- a/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp
@@ -13,6 +13,7 @@
#include <deque>
#include <cassert>
+#include "test_allocator.h"
// Flag that makes the copy constructor for CMyClass throw an exception
static bool gCopyConstructorShouldThow = false;
@@ -66,6 +67,7 @@
int main()
{
CMyClass instance(42);
+ {
std::deque<CMyClass> vec;
vec.push_front(instance);
@@ -74,8 +76,26 @@
gCopyConstructorShouldThow = true;
try {
vec.push_front(instance);
+ assert(false);
+ }
+ catch (...) {
+ gCopyConstructorShouldThow = false;
+ assert(vec==vec2);
+ }
+ }
+
+ {
+ typedef std::deque<CMyClass, test_allocator<CMyClass> > C;
+ C vec;
+ C vec2(vec);
+
+ C::allocator_type::throw_after = 1;
+ try {
+ vec.push_front(instance);
+ assert(false);
}
catch (...) {
assert(vec==vec2);
}
+ }
}
diff --git a/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp b/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp
index 3c94eb0..83bcac8 100644
--- a/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp
@@ -12,6 +12,9 @@
// void swap(deque& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value);
// This tests a conforming extension
@@ -33,6 +36,19 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -54,7 +70,21 @@
{
typedef std::deque<MoveOnly, some_alloc<MoveOnly>> C;
C c1, c2;
+#if TEST_STD_VER >= 14
+ // In c++14, if POCS is set, swapping the allocator is required not to throw
+ static_assert( noexcept(swap(c1, c2)), "");
+#else
static_assert(!noexcept(swap(c1, c2)), "");
+#endif
}
+#if TEST_STD_VER >= 14
+ {
+ typedef std::deque<MoveOnly, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ // if the allocators are always equal, then the swap can be noexcept
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp
index 296ffcd..349a387 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.ops/splice_after_one.pass.cpp
@@ -15,6 +15,7 @@
#include <cassert>
#include <iterator>
+#include "test_macros.h"
#include "min_allocator.h"
typedef int T;
@@ -44,7 +45,6 @@
{
typename C::const_iterator i = c.begin();
int n = 0;
- int d = 1;
if (p == f || p == f+1)
{
for (n = 0; n < size_t1; ++n, ++i)
@@ -106,7 +106,7 @@
}
}
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
// splicing different containers
typedef std::forward_list<T, min_allocator<T>> C;
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp
index ca673b5..9f01fed 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.spec/equal.pass.cpp
@@ -22,12 +22,12 @@
#include <algorithm>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
void test(int N, int M)
{
- typedef typename C::value_type T;
C c1;
for (int i = 0; i < N; ++i)
c1.push_front(i);
@@ -52,7 +52,7 @@
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
test<std::forward_list<int> >(i, j);
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
test<std::forward_list<int, min_allocator<int>> >(i, j);
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp
index 42e245d..e65e064 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.spec/relational.pass.cpp
@@ -30,12 +30,12 @@
#include <algorithm>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
template <class C>
void test(int N, int M)
{
- typedef typename C::value_type T;
C c1;
for (int i = 0; i < N; ++i)
c1.push_front(i);
@@ -57,7 +57,7 @@
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
test<std::forward_list<int> >(i, j);
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
test<std::forward_list<int, min_allocator<int>> >(i, j);
diff --git a/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.pass.cpp b/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.pass.cpp
index e36ba5b..cbe8142 100644
--- a/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.pass.cpp
+++ b/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.pass.cpp
@@ -12,6 +12,9 @@
// void swap(forward_list& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(is_always_equal<allocator_type>::value);
// This tests a conforming extension
@@ -33,6 +36,19 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -54,7 +70,21 @@
{
typedef std::forward_list<MoveOnly, some_alloc<MoveOnly>> C;
C c1, c2;
+#if TEST_STD_VER >= 14
+ // In c++14, if POCS is set, swapping the allocator is required not to throw
+ static_assert( noexcept(swap(c1, c2)), "");
+#else
static_assert(!noexcept(swap(c1, c2)), "");
+#endif
}
+#if TEST_STD_VER >= 14
+ {
+ typedef std::forward_list<MoveOnly, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ // if the allocators are always equal, then the swap can be noexcept
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp b/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp
index d69deac..a7f1917 100644
--- a/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp
+++ b/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp
@@ -12,7 +12,7 @@
// template <InputIterator Iter>
// iterator insert(const_iterator position, Iter first, Iter last);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
diff --git a/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp b/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp
index a552e1f..eeb74b8 100644
--- a/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp
+++ b/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp
@@ -11,7 +11,7 @@
// iterator insert(const_iterator position, size_type n, const value_type& x);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
diff --git a/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp b/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp
index 093ad42..406e93a 100644
--- a/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp
+++ b/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp
@@ -11,7 +11,7 @@
// iterator insert(const_iterator position, const value_type& x);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#if _LIBCPP_DEBUG >= 1
#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
diff --git a/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp b/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp
index 54ae359..9c83ad5 100644
--- a/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp
@@ -12,6 +12,9 @@
// void swap(list& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value);
// This tests a conforming extension
@@ -33,6 +36,19 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -54,7 +70,21 @@
{
typedef std::list<MoveOnly, some_alloc<MoveOnly>> C;
C c1, c2;
+#if TEST_STD_VER >= 14
+ // In c++14, if POCS is set, swapping the allocator is required not to throw
+ static_assert( noexcept(swap(c1, c2)), "");
+#else
static_assert(!noexcept(swap(c1, c2)), "");
+#endif
}
+#if TEST_STD_VER >= 14
+ {
+ typedef std::list<MoveOnly, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ // if the allocators are always equal, then the swap can be noexcept
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
index d3d6670..0782409 100644
--- a/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/construct_default.pass.cpp
@@ -15,6 +15,7 @@
#include <vector>
#include <cassert>
+#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"
@@ -22,11 +23,16 @@
void
test0()
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(C{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" );
+#endif
C c;
assert(c.__invariants());
assert(c.empty());
assert(c.get_allocator() == typename C::allocator_type());
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
C c1 = {};
assert(c1.__invariants());
assert(c1.empty());
@@ -38,6 +44,11 @@
void
test1(const typename C::allocator_type& a)
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(C{typename C::allocator_type{}})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible<typename C::allocator_type>::value), "" );
+#endif
C c(a);
assert(c.__invariants());
assert(c.empty());
@@ -50,7 +61,7 @@
test0<std::vector<bool> >();
test1<std::vector<bool, test_allocator<bool> > >(test_allocator<bool>(3));
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
test0<std::vector<bool, min_allocator<bool>> >();
test1<std::vector<bool, min_allocator<bool> > >(min_allocator<bool>());
diff --git a/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
index ab32bd0..132186b 100644
--- a/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/move_noexcept.pass.cpp
@@ -43,7 +43,12 @@
}
{
typedef std::vector<bool, some_alloc<bool>> C;
+ // In C++17, move constructors for allocators are not allowed to throw
+#if TEST_STD_VER > 14
+ static_assert( std::is_nothrow_move_constructible<C>::value, "");
+#else
static_assert(!std::is_nothrow_move_constructible<C>::value, "");
+#endif
}
#endif
}
diff --git a/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp b/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp
index bcaf161..6f36473 100644
--- a/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(vector& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
+// allocator_traits<Allocator>::is_always_equal::value);
// This tests a conforming extension
@@ -32,6 +36,19 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -53,7 +70,21 @@
{
typedef std::vector<bool, some_alloc<bool>> C;
C c1, c2;
+#if TEST_STD_VER >= 14
+ // In c++14, if POCS is set, swapping the allocator is required not to throw
+ static_assert( noexcept(swap(c1, c2)), "");
+#else
static_assert(!noexcept(swap(c1, c2)), "");
+#endif
}
+#if TEST_STD_VER >= 14
+ {
+ typedef std::vector<bool, some_alloc2<bool>> C;
+ C c1, c2;
+ // if the allocators are always equal, then the swap can be noexcept
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/sequences/vector/contiguous.pass.cpp b/test/std/containers/sequences/vector/contiguous.pass.cpp
new file mode 100644
index 0000000..32f3807
--- /dev/null
+++ b/test/std/containers/sequences/vector/contiguous.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// An vector is a contiguous container
+
+#include <vector>
+#include <cassert>
+
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+template <class C>
+void test_contiguous ( const C &c )
+{
+ for ( size_t i = 0; i < c.size(); ++i )
+ assert ( *(c.begin() + i) == *(std::addressof(*c.begin()) + i));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ typedef std::vector<T> C;
+ test_contiguous(C());
+ test_contiguous(C(3, 5));
+ }
+
+ {
+ typedef double T;
+ typedef test_allocator<T> A;
+ typedef std::vector<T, A> C;
+ test_contiguous(C(A(3)));
+ test_contiguous(C(7, 9.0, A(5)));
+ }
+#if __cplusplus >= 201103L
+ {
+ typedef double T;
+ typedef min_allocator<T> A;
+ typedef std::vector<T, A> C;
+ test_contiguous(C(A{}));
+ test_contiguous(C(9, 11.0, A{}));
+ }
+#endif
+}
diff --git a/test/std/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp b/test/std/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
index f5c06b1..3cb0b3b 100644
--- a/test/std/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
@@ -17,30 +17,39 @@
#include "min_allocator.h"
#include "asan_testing.h"
-int main()
+template <typename Vec>
+void test ( Vec &v )
{
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
+ v.assign({3, 4, 5, 6});
+ assert(v.size() == 4);
+ assert(is_contiguous_container_asan_correct(v));
+ assert(v[0] == 3);
+ assert(v[1] == 4);
+ assert(v[2] == 5);
+ assert(v[3] == 6);
+#endif
+}
+
+int main()
+{
{
- std::vector<int> d;
- d.assign({3, 4, 5, 6});
- assert(d.size() == 4);
- assert(is_contiguous_container_asan_correct(d));
- assert(d[0] == 3);
- assert(d[1] == 4);
- assert(d[2] == 5);
- assert(d[3] == 6);
+ typedef std::vector<int> V;
+ V d1;
+ V d2;
+ d2.reserve(10); // no reallocation during assign.
+ test(d1);
+ test(d2);
}
+
#if __cplusplus >= 201103L
{
- std::vector<int, min_allocator<int>> d;
- d.assign({3, 4, 5, 6});
- assert(d.size() == 4);
- assert(is_contiguous_container_asan_correct(d));
- assert(d[0] == 3);
- assert(d[1] == 4);
- assert(d[2] == 5);
- assert(d[3] == 6);
+ typedef std::vector<int, min_allocator<int>> V;
+ V d1;
+ V d2;
+ d2.reserve(10); // no reallocation during assign.
+ test(d1);
+ test(d2);
}
#endif
-#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
}
diff --git a/test/std/containers/sequences/vector/vector.cons/assign_size_value.pass.cpp b/test/std/containers/sequences/vector/vector.cons/assign_size_value.pass.cpp
new file mode 100644
index 0000000..e1b30bf
--- /dev/null
+++ b/test/std/containers/sequences/vector/vector.cons/assign_size_value.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// void assign(size_type n, const_reference v);
+
+#include <vector>
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+
+#include "min_allocator.h"
+#include "asan_testing.h"
+
+bool is6(int x) { return x == 6; }
+
+template <typename Vec>
+void test ( Vec &v )
+{
+ v.assign(5, 6);
+ assert(v.size() == 5);
+ assert(is_contiguous_container_asan_correct(v));
+ assert(std::all_of(v.begin(), v.end(), is6));
+}
+
+int main()
+{
+ {
+ typedef std::vector<int> V;
+ V d1;
+ V d2;
+ d2.reserve(10); // no reallocation during assign.
+ test(d1);
+ test(d2);
+ }
+
+#if __cplusplus >= 201103L
+ {
+ typedef std::vector<int, min_allocator<int>> V;
+ V d1;
+ V d2;
+ d2.reserve(10); // no reallocation during assign.
+ test(d1);
+ test(d2);
+ }
+#endif
+}
diff --git a/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp
index 75772be..5e87c07 100644
--- a/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/construct_default.pass.cpp
@@ -9,11 +9,13 @@
// <vector>
-// vector(const Alloc& = Alloc());
+// vector();
+// vector(const Alloc&);
#include <vector>
#include <cassert>
+#include "test_macros.h"
#include "test_allocator.h"
#include "../../../NotConstructible.h"
#include "../../../stack_allocator.h"
@@ -24,12 +26,17 @@
void
test0()
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(C{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(C()) == noexcept(typename C::allocator_type())), "" );
+#endif
C c;
assert(c.__invariants());
assert(c.empty());
assert(c.get_allocator() == typename C::allocator_type());
assert(is_contiguous_container_asan_correct(c));
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
C c1 = {};
assert(c1.__invariants());
assert(c1.empty());
@@ -42,6 +49,11 @@
void
test1(const typename C::allocator_type& a)
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(C{typename C::allocator_type{}})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(C(typename C::allocator_type())) == std::is_nothrow_copy_constructible<typename C::allocator_type>::value), "" );
+#endif
C c(a);
assert(c.__invariants());
assert(c.empty());
@@ -62,7 +74,7 @@
std::vector<int, stack_allocator<int, 10> > v;
assert(v.empty());
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
test0<std::vector<int, min_allocator<int>> >();
test0<std::vector<NotConstructible, min_allocator<NotConstructible>> >();
diff --git a/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp
index 471c1d4..60f7b72 100644
--- a/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/default_noexcept.pass.cpp
@@ -17,6 +17,7 @@
#include <vector>
#include <cassert>
+#include "test_macros.h"
#include "MoveOnly.h"
#include "test_allocator.h"
diff --git a/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp
index 46cad99..b7bbfaa 100644
--- a/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp
@@ -44,7 +44,12 @@
}
{
typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C;
+ // In C++17, move constructors for allocators are not allowed to throw
+#if TEST_STD_VER > 14
+ static_assert( std::is_nothrow_move_constructible<C>::value, "");
+#else
static_assert(!std::is_nothrow_move_constructible<C>::value, "");
+#endif
}
#endif
}
diff --git a/test/std/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp b/test/std/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp
index 92d8756..1d00ff3 100644
--- a/test/std/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp
+++ b/test/std/containers/sequences/vector/vector.special/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(vector& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
+// allocator_traits<Allocator>::is_always_equal::value);
// This tests a conforming extension
@@ -33,6 +37,19 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -54,7 +71,21 @@
{
typedef std::vector<MoveOnly, some_alloc<MoveOnly>> C;
C c1, c2;
+#if TEST_STD_VER >= 14
+ // In c++14, if POCS is set, swapping the allocator is required not to throw
+ static_assert( noexcept(swap(c1, c2)), "");
+#else
static_assert(!noexcept(swap(c1, c2)), "");
+#endif
}
+#if TEST_STD_VER >= 14
+ {
+ typedef std::vector<MoveOnly, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ // if the allocators are always equal, then the swap can be noexcept
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/unord/unord.map/bucket_count.pass.cpp b/test/std/containers/unord/unord.map/bucket_count.pass.cpp
index d3e80d8..bc37337 100644
--- a/test/std/containers/unord/unord.map/bucket_count.pass.cpp
+++ b/test/std/containers/unord/unord.map/bucket_count.pass.cpp
@@ -19,20 +19,18 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
- typedef C::const_iterator I;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.bucket_count() == 0);
}
{
typedef std::unordered_map<int, std::string> C;
- typedef C::const_iterator I;
typedef std::pair<int, std::string> P;
P a[] =
{
@@ -48,19 +46,16 @@
const C c(std::begin(a), std::end(a));
assert(c.bucket_count() >= 11);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
- typedef C::const_iterator I;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.bucket_count() == 0);
}
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
- typedef C::const_iterator I;
typedef std::pair<int, std::string> P;
P a[] =
{
diff --git a/test/std/containers/unord/unord.map/compare.pass.cpp b/test/std/containers/unord/unord.map/compare.pass.cpp
index 8979a3a..ea6d02f 100644
--- a/test/std/containers/unord/unord.map/compare.pass.cpp
+++ b/test/std/containers/unord/unord.map/compare.pass.cpp
@@ -17,6 +17,7 @@
// http://llvm.org/bugs/show_bug.cgi?id=16549
#include <unordered_map>
+#include <cassert>
struct Key {
template <typename T> Key(const T&) {}
@@ -35,8 +36,12 @@
int
main()
{
- std::unordered_map<Key, int>::iterator it =
- std::unordered_map<Key, int>().find(Key(0));
- std::pair<std::unordered_map<Key, int>::iterator, bool> result =
- std::unordered_map<Key, int>().insert(std::make_pair(Key(0), 0));
+ typedef std::unordered_map<Key, int> MapT;
+ typedef MapT::iterator Iter;
+ MapT map;
+ Iter it = map.find(Key(0));
+ assert(it == map.end());
+ std::pair<Iter, bool> result = map.insert(std::make_pair(Key(0), 42));
+ assert(result.second);
+ assert(result.first->second == 42);
}
diff --git a/test/std/containers/unord/unord.map/load_factor.pass.cpp b/test/std/containers/unord/unord.map/load_factor.pass.cpp
index 472e41a..b25c019 100644
--- a/test/std/containers/unord/unord.map/load_factor.pass.cpp
+++ b/test/std/containers/unord/unord.map/load_factor.pass.cpp
@@ -20,6 +20,7 @@
#include <cassert>
#include <cfloat>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
@@ -43,11 +44,10 @@
}
{
typedef std::unordered_map<int, std::string> C;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.load_factor() == 0);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
@@ -69,7 +69,6 @@
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.load_factor() == 0);
}
diff --git a/test/std/containers/unord/unord.map/max_bucket_count.pass.cpp b/test/std/containers/unord/unord.map/max_bucket_count.pass.cpp
index b4ca8eb..08f014d 100644
--- a/test/std/containers/unord/unord.map/max_bucket_count.pass.cpp
+++ b/test/std/containers/unord/unord.map/max_bucket_count.pass.cpp
@@ -19,23 +19,20 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
- typedef C::const_iterator I;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.max_bucket_count() > 0);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
- typedef C::const_iterator I;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.max_bucket_count() > 0);
}
diff --git a/test/std/containers/unord/unord.map/max_load_factor.pass.cpp b/test/std/containers/unord/unord.map/max_load_factor.pass.cpp
index 69fd70d..b19a6e6 100644
--- a/test/std/containers/unord/unord.map/max_load_factor.pass.cpp
+++ b/test/std/containers/unord/unord.map/max_load_factor.pass.cpp
@@ -16,44 +16,37 @@
// float max_load_factor() const;
// void max_load_factor(float mlf);
-#ifdef _LIBCPP_DEBUG
-#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
-#endif
-
#include <unordered_map>
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
int main()
{
{
typedef std::unordered_map<int, std::string> C;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.max_load_factor() == 1);
}
{
typedef std::unordered_map<int, std::string> C;
- typedef std::pair<int, std::string> P;
C c;
assert(c.max_load_factor() == 1);
c.max_load_factor(2.5);
assert(c.max_load_factor() == 2.5);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
- typedef std::pair<int, std::string> P;
const C c;
assert(c.max_load_factor() == 1);
}
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
- typedef std::pair<int, std::string> P;
C c;
assert(c.max_load_factor() == 1);
c.max_load_factor(2.5);
diff --git a/test/std/containers/unord/unord.map/swap_member.pass.cpp b/test/std/containers/unord/unord.map/swap_member.pass.cpp
index 8ab1eb6..0f98b66 100644
--- a/test/std/containers/unord/unord.map/swap_member.pass.cpp
+++ b/test/std/containers/unord/unord.map/swap_member.pass.cpp
@@ -21,6 +21,7 @@
#include "../../test_compare.h"
#include "../../test_hash.h"
+#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"
@@ -31,7 +32,6 @@
typedef test_compare<std::equal_to<int> > Compare;
typedef test_allocator<std::pair<const int, std::string> > Alloc;
typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
- typedef std::pair<int, std::string> P;
C c1(0, Hash(1), Compare(1), Alloc(1));
C c2(0, Hash(2), Compare(2), Alloc(2));
c2.max_load_factor(2);
@@ -212,7 +212,6 @@
typedef test_compare<std::equal_to<int> > Compare;
typedef other_allocator<std::pair<const int, std::string> > Alloc;
typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
- typedef std::pair<int, std::string> P;
C c1(0, Hash(1), Compare(1), Alloc(1));
C c2(0, Hash(2), Compare(2), Alloc(2));
c2.max_load_factor(2);
@@ -387,13 +386,12 @@
assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
assert(c2.max_load_factor() == 1);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef test_hash<std::hash<int> > Hash;
typedef test_compare<std::equal_to<int> > Compare;
typedef min_allocator<std::pair<const int, std::string> > Alloc;
typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
- typedef std::pair<int, std::string> P;
C c1(0, Hash(1), Compare(1), Alloc());
C c2(0, Hash(2), Compare(2), Alloc());
c2.max_load_factor(2);
diff --git a/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp b/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
index 18e6683..1420204 100644
--- a/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.cnstr/move.pass.cpp
@@ -15,6 +15,8 @@
// unordered_map(unordered_map&& u);
+// UNSUPPORTED: c++98, c++03
+
#include <unordered_map>
#include <string>
#include <cassert>
@@ -27,23 +29,12 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
typedef std::unordered_map<int, std::string,
test_hash<std::hash<int> >,
test_compare<std::equal_to<int> >,
test_allocator<std::pair<const int, std::string> >
> C;
- typedef std::pair<int, std::string> P;
- P a[] =
- {
- P(1, "one"),
- P(2, "two"),
- P(3, "three"),
- P(4, "four"),
- P(1, "four"),
- P(2, "four"),
- };
C c0(7,
test_hash<std::hash<int> >(8),
test_compare<std::equal_to<int> >(9),
@@ -105,23 +96,12 @@
assert(c0.empty());
}
-#if __cplusplus >= 201103L
{
typedef std::unordered_map<int, std::string,
test_hash<std::hash<int> >,
test_compare<std::equal_to<int> >,
min_allocator<std::pair<const int, std::string> >
> C;
- typedef std::pair<int, std::string> P;
- P a[] =
- {
- P(1, "one"),
- P(2, "two"),
- P(3, "three"),
- P(4, "four"),
- P(1, "four"),
- P(2, "four"),
- };
C c0(7,
test_hash<std::hash<int> >(8),
test_compare<std::equal_to<int> >(9),
@@ -183,7 +163,6 @@
assert(c0.empty());
}
-#endif
#if _LIBCPP_DEBUG >= 1
{
std::unordered_map<int, int> s1 = {{1, 1}, {2, 2}, {3, 3}};
@@ -195,5 +174,4 @@
assert(s2.size() == 2);
}
#endif
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/clear.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/clear.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/clear.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/emplace.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/emplace.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/emplace.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/emplace.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/emplace_hint.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/emplace_hint.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_const_iter.pass.cpp
similarity index 73%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_const_iter.pass.cpp
index 422dbe4..803ecb5 100644
--- a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_const_iter.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_const_iter.pass.cpp
@@ -19,8 +19,18 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator==(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+struct Hash { size_t operator() (const TemplateConstructor &) const { return 0; } };
+
int main()
{
{
@@ -37,13 +47,13 @@
};
C c(a, a + sizeof(a)/sizeof(a[0]));
C::const_iterator i = c.find(2);
- C::iterator j = c.erase(i);
+ c.erase(i);
assert(c.size() == 3);
assert(c.at(1) == "one");
assert(c.at(3) == "three");
assert(c.at(4) == "four");
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
@@ -59,11 +69,25 @@
};
C c(a, a + sizeof(a)/sizeof(a[0]));
C::const_iterator i = c.find(2);
- C::iterator j = c.erase(i);
+ c.erase(i);
assert(c.size() == 3);
assert(c.at(1) == "one");
assert(c.at(3) == "three");
assert(c.at(4) == "four");
}
#endif
+#if TEST_STD_VER >= 14
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::unordered_map<T, int, Hash> C;
+ typedef C::iterator I;
+
+ C m;
+ T a{0};
+ I it = m.find(a);
+ if (it != m.end())
+ m.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db1.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_db1.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db1.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_db1.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db2.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_db2.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_db2.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_db2.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db1.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db1.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db1.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db1.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db2.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db2.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db2.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db2.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db3.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db3.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db3.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db3.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db4.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db4.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_iter_iter_db4.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_iter_iter_db4.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_key.pass.cpp
similarity index 97%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_key.pass.cpp
index 0e8ef8b..cdd19eb 100644
--- a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_key.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_key.pass.cpp
@@ -19,15 +19,16 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "min_allocator.h"
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
template <typename Unordered>
bool only_deletions ( const Unordered &whole, const Unordered &part ) {
typename Unordered::const_iterator w = whole.begin();
typename Unordered::const_iterator p = part.begin();
-
- while ( w != whole.end () && p != part.end()) {
+
+ while ( w != whole.end () && p != part.end()) {
if ( *w == *p )
p++;
w++;
@@ -96,7 +97,7 @@
assert(c.erase(3) == 0);
assert(c.size() == 0);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>,
min_allocator<std::pair<const int, std::string>>> C;
@@ -161,7 +162,7 @@
m[i] = i;
m2[i] = i;
}
-
+
C::iterator i = m2.begin();
int ctr = 0;
while (i != m2.end()) {
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/erase_range.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/erase_range.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/erase_range.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_const_lvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_const_lvalue.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/insert_const_lvalue.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/insert_const_lvalue.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_hint_const_lvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/insert_hint_const_lvalue.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_const_lvalue.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_hint_rvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/insert_hint_rvalue.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/insert_hint_rvalue.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_init.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_init.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/insert_init.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/insert_init.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/insert_or_assign.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_or_assign.pass.cpp
new file mode 100644
index 0000000..a4d8abc
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_or_assign.pass.cpp
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// template <class M>
+// pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
+// template <class M>
+// pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
+// template <class M>
+// iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
+// template <class M>
+// iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
+
+#include <unordered_map>
+#include <cassert>
+#include <tuple>
+
+
+class Moveable
+{
+ Moveable(const Moveable&);
+ Moveable& operator=(const Moveable&);
+
+ int int_;
+ double double_;
+public:
+ Moveable() : int_(0), double_(0) {}
+ Moveable(int i, double d) : int_(i), double_(d) {}
+ Moveable(Moveable&& x)
+ : int_(x.int_), double_(x.double_)
+ {x.int_ = -1; x.double_ = -1;}
+ Moveable& operator=(Moveable&& x)
+ {int_ = x.int_; x.int_ = -1;
+ double_ = x.double_; x.double_ = -1;
+ return *this;
+ }
+
+ bool operator==(const Moveable& x) const
+ {return int_ == x.int_ && double_ == x.double_;}
+ bool operator<(const Moveable& x) const
+ {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
+ size_t hash () const { return std::hash<int>()(int_) + std::hash<double>()(double_); }
+
+ int get() const {return int_;}
+ bool moved() const {return int_ == -1;}
+};
+
+namespace std {
+ template <> struct hash<Moveable> {
+ size_t operator () (const Moveable &m) const { return m.hash(); }
+ };
+}
+
+int main()
+{
+
+ { // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
+ typedef std::unordered_map<int, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace ( i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+
+ for (int i=0; i < 20; i += 2)
+ {
+ Moveable mv(i+1, i+1);
+ r = m.insert_or_assign(i, std::move(mv));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(mv.moved()); // was moved from
+ assert(r.first->first == i); // key
+ assert(r.first->second.get() == i+1); // value
+ }
+
+ Moveable mv1(5, 5.0);
+ r = m.insert_or_assign(-1, std::move(mv1));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv1.moved()); // was moved from
+ assert(r.first->first == -1); // key
+ assert(r.first->second.get() == 5); // value
+
+ Moveable mv2(9, 9.0);
+ r = m.insert_or_assign(3, std::move(mv2));
+ assert(m.size() == 12);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(r.first->first == 3); // key
+ assert(r.first->second.get() == 9); // value
+
+ Moveable mv3(-1, 5.0);
+ r = m.insert_or_assign(117, std::move(mv3));
+ assert(m.size() == 13);
+ assert(r.second); // was inserted
+ assert(mv3.moved()); // was moved from
+ assert(r.first->first == 117); // key
+ assert(r.first->second.get() == -1); // value
+ }
+ { // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
+ typedef std::unordered_map<Moveable, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.insert_or_assign(std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(!mvkey1.moved()); // was not moved from
+ assert(mv1.moved()); // was moved from
+ assert(r.first->first == mvkey1); // key
+ assert(r.first->second.get() == 4); // value
+
+ Moveable mvkey2(3, 3.0);
+ Moveable mv2(5, 5.0);
+ r = m.try_emplace(std::move(mvkey2), std::move(mv2));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r.first->first.get() == 3); // key
+ assert(r.first->second.get() == 5); // value
+ }
+ { // iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
+ typedef std::unordered_map<int, Moveable> M;
+ M m;
+ M::iterator r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace ( i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+ M::const_iterator it = m.find(2);
+
+ Moveable mv1(3, 3.0);
+ r = m.insert_or_assign(it, 2, std::move(mv1));
+ assert(m.size() == 10);
+ assert(mv1.moved()); // was moved from
+ assert(r->first == 2); // key
+ assert(r->second.get() == 3); // value
+
+ Moveable mv2(5, 5.0);
+ r = m.insert_or_assign(it, 3, std::move(mv2));
+ assert(m.size() == 11);
+ assert(mv2.moved()); // was moved from
+ assert(r->first == 3); // key
+ assert(r->second.get() == 5); // value
+ }
+ { // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
+ typedef std::unordered_map<Moveable, Moveable> M;
+ M m;
+ M::iterator r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+ M::const_iterator it = std::next(m.cbegin());
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.insert_or_assign(it, std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(mv1.moved()); // was moved from
+ assert(!mvkey1.moved()); // was not moved from
+ assert(r->first == mvkey1); // key
+ assert(r->second.get() == 4); // value
+
+ Moveable mvkey2(3, 3.0);
+ Moveable mv2(5, 5.0);
+ r = m.insert_or_assign(it, std::move(mvkey2), std::move(mv2));
+ assert(m.size() == 11);
+ assert(mv2.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r->first.get() == 3); // key
+ assert(r->second.get() == 5); // value
+ }
+
+}
\ No newline at end of file
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_range.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/insert_range.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/insert_range.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unorder.map.modifiers/insert_rvalue.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue.pass.cpp
similarity index 100%
rename from test/std/containers/unord/unord.map/unorder.map.modifiers/insert_rvalue.pass.cpp
rename to test/std/containers/unord/unord.map/unord.map.modifiers/insert_rvalue.pass.cpp
diff --git a/test/std/containers/unord/unord.map/unord.map.modifiers/try.emplace.pass.cpp b/test/std/containers/unord/unord.map/unord.map.modifiers/try.emplace.pass.cpp
new file mode 100644
index 0000000..eabcf2e
--- /dev/null
+++ b/test/std/containers/unord/unord.map/unord.map.modifiers/try.emplace.pass.cpp
@@ -0,0 +1,190 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <unordered_map>
+
+// class unordered_map
+
+// template <class... Args>
+// pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
+// template <class... Args>
+// pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
+// template <class... Args>
+// iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
+// template <class... Args>
+// iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
+
+#include <__config>
+#include <unordered_map>
+#include <cassert>
+#include <tuple>
+
+class Moveable
+{
+ Moveable(const Moveable&);
+ Moveable& operator=(const Moveable&);
+
+ int int_;
+ double double_;
+public:
+ Moveable() : int_(0), double_(0) {}
+ Moveable(int i, double d) : int_(i), double_(d) {}
+ Moveable(Moveable&& x)
+ : int_(x.int_), double_(x.double_)
+ {x.int_ = -1; x.double_ = -1;}
+ Moveable& operator=(Moveable&& x)
+ {int_ = x.int_; x.int_ = -1;
+ double_ = x.double_; x.double_ = -1;
+ return *this;
+ }
+
+ bool operator==(const Moveable& x) const
+ {return int_ == x.int_ && double_ == x.double_;}
+ bool operator<(const Moveable& x) const
+ {return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);}
+ size_t hash () const { return std::hash<int>()(int_) + std::hash<double>()(double_); }
+
+ int get() const {return int_;}
+ bool moved() const {return int_ == -1;}
+};
+
+namespace std {
+ template <> struct hash<Moveable> {
+ size_t operator () (const Moveable &m) const { return m.hash(); }
+ };
+}
+
+int main()
+{
+
+ { // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
+ typedef std::unordered_map<int, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace (i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+
+ Moveable mv1(3, 3.0);
+ for (int i=0; i < 20; i += 2)
+ {
+ r = m.try_emplace(i, std::move(mv1));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(!mv1.moved()); // was not moved from
+ assert(r.first->first == i); // key
+ }
+
+ r = m.try_emplace(-1, std::move(mv1));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv1.moved()); // was moved from
+ assert(r.first->first == -1); // key
+ assert(r.first->second.get() == 3); // value
+
+ Moveable mv2(5, 3.0);
+ r = m.try_emplace(5, std::move(mv2));
+ assert(m.size() == 12);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(r.first->first == 5); // key
+ assert(r.first->second.get() == 5); // value
+
+ Moveable mv3(-1, 3.0);
+ r = m.try_emplace(117, std::move(mv2));
+ assert(m.size() == 13);
+ assert(r.second); // was inserted
+ assert(mv2.moved()); // was moved from
+ assert(r.first->first == 117); // key
+ assert(r.first->second.get() == -1); // value
+ }
+
+ { // pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
+ typedef std::unordered_map<Moveable, Moveable> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ R r;
+ for (int i = 0; i < 20; i += 2)
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.try_emplace(std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(!r.second); // was not inserted
+ assert(!mv1.moved()); // was not moved from
+ assert(!mvkey1.moved()); // was not moved from
+ assert(r.first->first == mvkey1); // key
+
+ Moveable mvkey2(3, 3.0);
+ r = m.try_emplace(std::move(mvkey2), std::move(mv1));
+ assert(m.size() == 11);
+ assert(r.second); // was inserted
+ assert(mv1.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r.first->first.get() == 3); // key
+ assert(r.first->second.get() == 4); // value
+ }
+
+ { // iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
+ typedef std::unordered_map<int, Moveable> M;
+ M m;
+ M::iterator r;
+ for (int i = 0; i < 20; i += 2)
+ m.try_emplace ( i, Moveable(i, (double) i));
+ assert(m.size() == 10);
+ M::const_iterator it = m.find(2);
+
+ Moveable mv1(3, 3.0);
+ for (int i=0; i < 20; i += 2)
+ {
+ r = m.try_emplace(it, i, std::move(mv1));
+ assert(m.size() == 10);
+ assert(!mv1.moved()); // was not moved from
+ assert(r->first == i); // key
+ assert(r->second.get() == i); // value
+ }
+
+ r = m.try_emplace(it, 3, std::move(mv1));
+ assert(m.size() == 11);
+ assert(mv1.moved()); // was moved from
+ assert(r->first == 3); // key
+ assert(r->second.get() == 3); // value
+ }
+
+ { // iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
+ typedef std::unordered_map<Moveable, Moveable> M;
+ M m;
+ M::iterator r;
+ for ( int i = 0; i < 20; i += 2 )
+ m.emplace ( Moveable(i, (double) i), Moveable(i+1, (double) i+1));
+ assert(m.size() == 10);
+ M::const_iterator it = std::next(m.cbegin());
+
+ Moveable mvkey1(2, 2.0);
+ Moveable mv1(4, 4.0);
+ r = m.try_emplace(it, std::move(mvkey1), std::move(mv1));
+ assert(m.size() == 10);
+ assert(!mv1.moved()); // was not moved from
+ assert(!mvkey1.moved()); // was not moved from
+ assert(r->first == mvkey1); // key
+
+ Moveable mvkey2(3, 3.0);
+ r = m.try_emplace(it, std::move(mvkey2), std::move(mv1));
+ assert(m.size() == 11);
+ assert(mv1.moved()); // was moved from
+ assert(mvkey2.moved()); // was moved from
+ assert(r->first.get() == 3); // key
+ assert(r->second.get() == 4); // value
+ }
+}
diff --git a/test/std/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp b/test/std/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp
index a986882..1056c23 100644
--- a/test/std/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp
@@ -10,8 +10,16 @@
// <unordered_map>
// void swap(unordered_map& c)
-// noexcept(!allocator_type::propagate_on_container_swap::value ||
-// __is_nothrow_swappable<allocator_type>::value);
+// noexcept(
+// (!allocator_type::propagate_on_container_swap::value ||
+// __is_nothrow_swappable<allocator_type>::value) &&
+// __is_nothrow_swappable<hasher>::value &&
+// __is_nothrow_swappable<key_equal>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Hash&>(), declval<Hash&>())) &&
+// noexcept(swap(declval<Pred&>(), declval<Pred&>())));
// This tests a conforming extension
@@ -31,6 +39,22 @@
};
template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
struct some_hash
{
typedef T value_type;
@@ -38,9 +62,62 @@
some_hash(const some_hash&);
};
+template <class T>
+struct some_hash2
+{
+ typedef T value_type;
+ some_hash2() {}
+ some_hash2(const some_hash2&);
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_hash2<T>&, some_hash2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
+
int main()
{
#if __has_feature(cxx_noexcept)
+ typedef std::pair<const MoveOnly, MoveOnly> MapType;
{
typedef std::unordered_map<MoveOnly, MoveOnly> C;
C c1, c2;
@@ -48,13 +125,13 @@
}
{
typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+ std::equal_to<MoveOnly>, test_allocator<MapType>> C;
C c1, c2;
static_assert(noexcept(swap(c1, c2)), "");
}
{
typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+ std::equal_to<MoveOnly>, other_allocator<MapType>> C;
C c1, c2;
static_assert(noexcept(swap(c1, c2)), "");
}
@@ -69,5 +146,54 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MapType>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
#endif
}
diff --git a/test/std/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp b/test/std/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp
index 7e04b8d..f3d51f6 100644
--- a/test/std/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp
+++ b/test/std/containers/unord/unord.map/unord.map.swap/swap_non_member.pass.cpp
@@ -21,6 +21,7 @@
#include "../../../test_compare.h"
#include "../../../test_hash.h"
+#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"
@@ -31,7 +32,6 @@
typedef test_compare<std::equal_to<int> > Compare;
typedef test_allocator<std::pair<const int, std::string> > Alloc;
typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
- typedef std::pair<int, std::string> P;
C c1(0, Hash(1), Compare(1), Alloc(1));
C c2(0, Hash(2), Compare(2), Alloc(2));
c2.max_load_factor(2);
@@ -212,7 +212,6 @@
typedef test_compare<std::equal_to<int> > Compare;
typedef other_allocator<std::pair<const int, std::string> > Alloc;
typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
- typedef std::pair<int, std::string> P;
C c1(0, Hash(1), Compare(1), Alloc(1));
C c2(0, Hash(2), Compare(2), Alloc(2));
c2.max_load_factor(2);
@@ -387,13 +386,12 @@
assert(std::distance(c2.cbegin(), c2.cend()) == c2.size());
assert(c2.max_load_factor() == 1);
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef test_hash<std::hash<int> > Hash;
typedef test_compare<std::equal_to<int> > Compare;
typedef min_allocator<std::pair<const int, std::string> > Alloc;
typedef std::unordered_map<int, std::string, Hash, Compare, Alloc> C;
- typedef std::pair<int, std::string> P;
C c1(0, Hash(1), Compare(1), Alloc());
C c2(0, Hash(2), Compare(2), Alloc());
c2.max_load_factor(2);
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp
index 25d6a7a..b31a4e5 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/erase_const_iter.pass.cpp
@@ -21,6 +21,15 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator==(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+struct Hash { size_t operator() (const TemplateConstructor &) const { return 0; } };
+
int main()
{
{
@@ -114,4 +123,18 @@
assert(std::distance(c.cbegin(), c.cend()) == c.size());
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::unordered_multimap<T, int, Hash> C;
+ typedef C::iterator I;
+
+ C m;
+ T a{0};
+ I it = m.find(a);
+ if (it != m.end())
+ m.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp b/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp
index c690bb6..37c8119 100644
--- a/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp
+++ b/test/std/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp
@@ -10,8 +10,16 @@
// <unordered_map>
// void swap(unordered_multimap& c)
-// noexcept(!allocator_type::propagate_on_container_swap::value ||
-// __is_nothrow_swappable<allocator_type>::value);
+// noexcept(
+// (!allocator_type::propagate_on_container_swap::value ||
+// __is_nothrow_swappable<allocator_type>::value) &&
+// __is_nothrow_swappable<hasher>::value &&
+// __is_nothrow_swappable<key_equal>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
+// __is_nothrow_swappable<hasher>::value &&
+// __is_nothrow_swappable<key_equal>::value);
// This tests a conforming extension
@@ -31,6 +39,22 @@
};
template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
struct some_hash
{
typedef T value_type;
@@ -38,9 +62,61 @@
some_hash(const some_hash&);
};
+template <class T>
+struct some_hash2
+{
+ typedef T value_type;
+ some_hash2() {}
+ some_hash2(const some_hash2&);
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_hash2<T>&, some_hash2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
+ typedef std::pair<const MoveOnly, MoveOnly> MapType;
{
typedef std::unordered_multimap<MoveOnly, MoveOnly> C;
C c1, c2;
@@ -48,13 +124,13 @@
}
{
typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, test_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+ std::equal_to<MoveOnly>, test_allocator<MapType>> C;
C c1, c2;
static_assert(noexcept(swap(c1, c2)), "");
}
{
typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>,
- std::equal_to<MoveOnly>, other_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
+ std::equal_to<MoveOnly>, other_allocator<MapType>> C;
C c1, c2;
static_assert(noexcept(swap(c1, c2)), "");
}
@@ -69,5 +145,54 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_multimap<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MapType>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/unord/unord.multiset/erase_const_iter.pass.cpp b/test/std/containers/unord/unord.multiset/erase_const_iter.pass.cpp
index 6a005d3..d3be2b6 100644
--- a/test/std/containers/unord/unord.multiset/erase_const_iter.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/erase_const_iter.pass.cpp
@@ -20,6 +20,15 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator==(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+struct Hash { size_t operator() (const TemplateConstructor &) const { return 0; } };
+
int main()
{
{
@@ -67,4 +76,18 @@
assert(c.count(4) == 1);
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::unordered_set<T, Hash> C;
+ typedef C::iterator I;
+
+ C m;
+ T a{0};
+ I it = m.find(a);
+ if (it != m.end())
+ m.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_noexcept.pass.cpp b/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_noexcept.pass.cpp
index 7dc653b..63642fc 100644
--- a/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_noexcept.pass.cpp
+++ b/test/std/containers/unord/unord.multiset/unord.multiset.swap/swap_noexcept.pass.cpp
@@ -10,8 +10,16 @@
// <unordered_set>
// void swap(unordered_multiset& c)
-// noexcept(!allocator_type::propagate_on_container_swap::value ||
-// __is_nothrow_swappable<allocator_type>::value);
+// noexcept(
+// (!allocator_type::propagate_on_container_swap::value ||
+// __is_nothrow_swappable<allocator_type>::value) &&
+// __is_nothrow_swappable<hasher>::value &&
+// __is_nothrow_swappable<key_equal>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Hash&>(), declval<Hash&>())) &&
+// noexcept(swap(declval<Pred&>(), declval<Pred&>())));
// This tests a conforming extension
@@ -31,6 +39,22 @@
};
template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
struct some_hash
{
typedef T value_type;
@@ -38,6 +62,57 @@
some_hash(const some_hash&);
};
+template <class T>
+struct some_hash2
+{
+ typedef T value_type;
+ some_hash2() {}
+ some_hash2(const some_hash2&);
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_hash2<T>&, some_hash2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -69,5 +144,55 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_multiset<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/containers/unord/unord.set/erase_const_iter.pass.cpp b/test/std/containers/unord/unord.set/erase_const_iter.pass.cpp
index 3a9cb58..4110953 100644
--- a/test/std/containers/unord/unord.set/erase_const_iter.pass.cpp
+++ b/test/std/containers/unord/unord.set/erase_const_iter.pass.cpp
@@ -20,6 +20,15 @@
#include "min_allocator.h"
+struct TemplateConstructor
+{
+ template<typename T>
+ TemplateConstructor (const T&) {}
+};
+
+bool operator==(const TemplateConstructor&, const TemplateConstructor&) { return false; }
+struct Hash { size_t operator() (const TemplateConstructor &) const { return 0; } };
+
int main()
{
{
@@ -64,4 +73,18 @@
assert(c.count(4) == 1);
}
#endif
+#if __cplusplus >= 201402L
+ {
+ // This is LWG #2059
+ typedef TemplateConstructor T;
+ typedef std::unordered_set<T, Hash> C;
+ typedef C::iterator I;
+
+ C m;
+ T a{0};
+ I it = m.find(a);
+ if (it != m.end())
+ m.erase(it);
+ }
+#endif
}
diff --git a/test/std/containers/unord/unord.set/unord.set.swap/swap_noexcept.pass.cpp b/test/std/containers/unord/unord.set/unord.set.swap/swap_noexcept.pass.cpp
index cba0923..5d74640 100644
--- a/test/std/containers/unord/unord.set/unord.set.swap/swap_noexcept.pass.cpp
+++ b/test/std/containers/unord/unord.set/unord.set.swap/swap_noexcept.pass.cpp
@@ -10,8 +10,16 @@
// <unordered_set>
// void swap(unordered_set& c)
-// noexcept(!allocator_type::propagate_on_container_swap::value ||
-// __is_nothrow_swappable<allocator_type>::value);
+// noexcept(
+// (!allocator_type::propagate_on_container_swap::value ||
+// __is_nothrow_swappable<allocator_type>::value) &&
+// __is_nothrow_swappable<hasher>::value &&
+// __is_nothrow_swappable<key_equal>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
+// noexcept(swap(declval<Hash&>(), declval<Hash&>())) &&
+// noexcept(swap(declval<Pred&>(), declval<Pred&>())));
// This tests a conforming extension
@@ -31,6 +39,22 @@
};
template <class T>
+struct some_comp2
+{
+ typedef T value_type;
+
+ some_comp2() {}
+ some_comp2(const some_comp2&) {}
+ void deallocate(void*, unsigned) {}
+ typedef std::true_type propagate_on_container_swap;
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
+#endif
+
+template <class T>
struct some_hash
{
typedef T value_type;
@@ -38,6 +62,57 @@
some_hash(const some_hash&);
};
+template <class T>
+struct some_hash2
+{
+ typedef T value_type;
+ some_hash2() {}
+ some_hash2(const some_hash2&);
+};
+
+#if TEST_STD_VER >= 14
+template <typename T>
+void swap(some_hash2<T>&, some_hash2<T>&) noexcept {}
+#endif
+
+template <class T>
+struct some_alloc
+{
+ typedef T value_type;
+
+ some_alloc() {}
+ some_alloc(const some_alloc&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::true_type propagate_on_container_swap;
+};
+
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct some_alloc3
+{
+ typedef T value_type;
+
+ some_alloc3() {}
+ some_alloc3(const some_alloc3&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::false_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -69,5 +144,55 @@
C c1, c2;
static_assert(!noexcept(swap(c1, c2)), "");
}
+
+#if TEST_STD_VER >= 14
+ { // POCS allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, throwable swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, throwable swap for hash, nothrow swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, throwable swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert(!noexcept(swap(c1, c2)), "");
+ }
+ { // POCS allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+ { // always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+
+ { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
+ typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
+ C c1, c2;
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.conv/convert_to_auto_ptr_ref.pass.cpp b/test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.conv/convert_to_auto_ptr_ref.pass.cpp
index f61a28e..a5db81e 100644
--- a/test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.conv/convert_to_auto_ptr_ref.pass.cpp
+++ b/test/std/depr/depr.auto.ptr/auto.ptr/auto.ptr.conv/convert_to_auto_ptr_ref.pass.cpp
@@ -24,6 +24,10 @@
B* p1 = new B(1);
std::auto_ptr<B> ap1(p1);
std::auto_ptr_ref<A> apr = ap1;
+ std::auto_ptr<A> ap2(apr);
+ assert(ap1.get() == nullptr);
+ assert(ap2.get() == p1);
+ ap2.release();
delete p1;
}
diff --git a/test/std/depr/depr.auto.ptr/auto.ptr/element_type.pass.cpp b/test/std/depr/depr.auto.ptr/auto.ptr/element_type.pass.cpp
index 2d1c2af..2565634 100644
--- a/test/std/depr/depr.auto.ptr/auto.ptr/element_type.pass.cpp
+++ b/test/std/depr/depr.auto.ptr/auto.ptr/element_type.pass.cpp
@@ -25,6 +25,8 @@
test()
{
static_assert((std::is_same<typename std::auto_ptr<T>::element_type, T>::value), "");
+ std::auto_ptr<T> p;
+ ((void)p);
}
int main()
@@ -32,5 +34,4 @@
test<int>();
test<double>();
test<void>();
- std::auto_ptr<void> p;
}
diff --git a/test/std/depr/depr.c.headers/inttypes_h.pass.cpp b/test/std/depr/depr.c.headers/inttypes_h.pass.cpp
index 4adf82d..a799aea 100644
--- a/test/std/depr/depr.c.headers/inttypes_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/inttypes_h.pass.cpp
@@ -631,7 +631,8 @@
int main()
{
{
- imaxdiv_t i1 = {0};
+ imaxdiv_t i1 = {0};
+ ((void)i1);
}
intmax_t i = 0;
static_assert((std::is_same<decltype(imaxabs(i)), intmax_t>::value), "");
diff --git a/test/std/depr/depr.c.headers/locale_h.pass.cpp b/test/std/depr/depr.c.headers/locale_h.pass.cpp
index 6ecf5a8..f5735b6 100644
--- a/test/std/depr/depr.c.headers/locale_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/locale_h.pass.cpp
@@ -42,7 +42,7 @@
int main()
{
- lconv lc;
+ lconv lc; ((void)lc);
static_assert((std::is_same<decltype(setlocale(0, "")), char*>::value), "");
static_assert((std::is_same<decltype(localeconv()), lconv*>::value), "");
}
diff --git a/test/std/depr/depr.c.headers/signal_h.pass.cpp b/test/std/depr/depr.c.headers/signal_h.pass.cpp
index a8ef5f9..83f45c9 100644
--- a/test/std/depr/depr.c.headers/signal_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/signal_h.pass.cpp
@@ -50,7 +50,7 @@
int main()
{
- sig_atomic_t sig;
+ sig_atomic_t sig; ((void)sig);
typedef void (*func)(int);
static_assert((std::is_same<decltype(signal(0, (func)0)), func>::value), "");
static_assert((std::is_same<decltype(raise(0)), int>::value), "");
diff --git a/test/std/depr/depr.c.headers/stdarg_h.pass.cpp b/test/std/depr/depr.c.headers/stdarg_h.pass.cpp
index 7a60902..f7d12b1 100644
--- a/test/std/depr/depr.c.headers/stdarg_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdarg_h.pass.cpp
@@ -32,4 +32,5 @@
int main()
{
va_list va;
+ ((void)va);
}
diff --git a/test/std/depr/depr.c.headers/stdio_h.pass.cpp b/test/std/depr/depr.c.headers/stdio_h.pass.cpp
index d4cfbc8..ba6714d 100644
--- a/test/std/depr/depr.c.headers/stdio_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdio_h.pass.cpp
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <type_traits>
+#include "test_macros.h"
#ifndef BUFSIZ
#error BUFSIZ not defined
@@ -78,14 +79,16 @@
#include <cstdarg>
-#pragma clang diagnostic ignored "-Wformat-zero-length"
+#pragma GCC diagnostic ignored "-Wformat-zero-length"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // for tmpnam
int main()
{
FILE* fp = 0;
fpos_t fpos = {0};
- size_t s = 0;
+ size_t s = 0; ((void)s);
char* cp = 0;
+ char arr[] = {'a', 'b'};
va_list va;
static_assert((std::is_same<decltype(remove("")), int>::value), "");
static_assert((std::is_same<decltype(rename("","")), int>::value), "");
@@ -117,7 +120,7 @@
static_assert((std::is_same<decltype(fputs("",fp)), int>::value), "");
static_assert((std::is_same<decltype(getc(fp)), int>::value), "");
static_assert((std::is_same<decltype(getchar()), int>::value), "");
-#if _LIBCPP_STD_VER < 14
+#if TEST_STD_VER < 14
static_assert((std::is_same<decltype(gets(cp)), char*>::value), "");
#endif
static_assert((std::is_same<decltype(putc(0,fp)), int>::value), "");
@@ -125,7 +128,7 @@
static_assert((std::is_same<decltype(puts("")), int>::value), "");
static_assert((std::is_same<decltype(ungetc(0,fp)), int>::value), "");
static_assert((std::is_same<decltype(fread((void*)0,0,0,fp)), size_t>::value), "");
- static_assert((std::is_same<decltype(fwrite((const void*)0,0,0,fp)), size_t>::value), "");
+ static_assert((std::is_same<decltype(fwrite((const void*)arr,1,0,fp)), size_t>::value), "");
static_assert((std::is_same<decltype(fgetpos(fp, &fpos)), int>::value), "");
static_assert((std::is_same<decltype(fseek(fp, 0,0)), int>::value), "");
static_assert((std::is_same<decltype(fsetpos(fp, &fpos)), int>::value), "");
diff --git a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
index 98b19c6..d1cc443 100644
--- a/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/stdlib_h.pass.cpp
@@ -34,10 +34,10 @@
int main()
{
- size_t s = 0;
- div_t d;
- ldiv_t ld;
- lldiv_t lld;
+ size_t s = 0; ((void)s);
+ div_t d; ((void)d);
+ ldiv_t ld; ((void)ld);
+ lldiv_t lld; ((void)lld);
char** endptr = 0;
static_assert((std::is_same<decltype(atof("")), double>::value), "");
static_assert((std::is_same<decltype(atoi("")), int>::value), "");
@@ -71,12 +71,14 @@
static_assert((std::is_same<decltype(div(0,0)), div_t>::value), "");
static_assert((std::is_same<decltype(ldiv(0L,0L)), ldiv_t>::value), "");
static_assert((std::is_same<decltype(lldiv(0LL,0LL)), lldiv_t>::value), "");
- static_assert((std::is_same<decltype(mblen("",0)), int>::value), "");
wchar_t* pw = 0;
const wchar_t* pwc = 0;
char* pc = 0;
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+ static_assert((std::is_same<decltype(mblen("",0)), int>::value), "");
static_assert((std::is_same<decltype(mbtowc(pw,"",0)), int>::value), "");
static_assert((std::is_same<decltype(wctomb(pc,L' ')), int>::value), "");
+#endif
static_assert((std::is_same<decltype(mbstowcs(pw,"",0)), size_t>::value), "");
static_assert((std::is_same<decltype(wcstombs(pc,pwc,0)), size_t>::value), "");
}
diff --git a/test/std/depr/depr.c.headers/string_h.pass.cpp b/test/std/depr/depr.c.headers/string_h.pass.cpp
index fc7f65d..afc784f 100644
--- a/test/std/depr/depr.c.headers/string_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/string_h.pass.cpp
@@ -41,7 +41,9 @@
static_assert((std::is_same<decltype(strrchr(cp, 0)), char*>::value), "");
static_assert((std::is_same<decltype(strspn(cpc, cpc)), size_t>::value), "");
static_assert((std::is_same<decltype(strstr(cp, cpc)), char*>::value), "");
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
static_assert((std::is_same<decltype(strtok(cp, cpc)), char*>::value), "");
+#endif
static_assert((std::is_same<decltype(memset(vp, 0, s)), void*>::value), "");
static_assert((std::is_same<decltype(strerror(0)), char*>::value), "");
static_assert((std::is_same<decltype(strlen(cpc)), size_t>::value), "");
diff --git a/test/std/depr/depr.c.headers/time_h.pass.cpp b/test/std/depr/depr.c.headers/time_h.pass.cpp
index c468693..0d229af 100644
--- a/test/std/depr/depr.c.headers/time_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/time_h.pass.cpp
@@ -22,7 +22,7 @@
int main()
{
- clock_t c = 0;
+ clock_t c = 0; ((void)c);
size_t s = 0;
time_t t = 0;
tm tmv = {0};
diff --git a/test/std/depr/depr.c.headers/wchar_h.pass.cpp b/test/std/depr/depr.c.headers/wchar_h.pass.cpp
index 68bea49..8d1c3b7 100644
--- a/test/std/depr/depr.c.headers/wchar_h.pass.cpp
+++ b/test/std/depr/depr.c.headers/wchar_h.pass.cpp
@@ -28,6 +28,10 @@
#error WEOF not defined
#endif
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wmissing-braces"
+#endif
+
int main()
{
mbstate_t mb = {0};
diff --git a/test/std/depr/exception.unexpected/unexpected.handler/unexpected_handler.pass.cpp b/test/std/depr/exception.unexpected/unexpected.handler/unexpected_handler.pass.cpp
index 7fab500..5879529 100644
--- a/test/std/depr/exception.unexpected/unexpected.handler/unexpected_handler.pass.cpp
+++ b/test/std/depr/exception.unexpected/unexpected.handler/unexpected_handler.pass.cpp
@@ -16,4 +16,5 @@
int main()
{
std::unexpected_handler p = f;
+ ((void)p);
}
diff --git a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.overview/error_category.pass.cpp b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.overview/error_category.pass.cpp
index 2353058..79162dd 100644
--- a/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.overview/error_category.pass.cpp
+++ b/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.overview/error_category.pass.cpp
@@ -16,4 +16,5 @@
int main()
{
std::error_category* p = 0;
+ ((void)p);
}
diff --git a/test/std/experimental/algorithms/alg.random.sample/sample.fail.cpp b/test/std/experimental/algorithms/alg.random.sample/sample.fail.cpp
new file mode 100644
index 0000000..eeb4373
--- /dev/null
+++ b/test/std/experimental/algorithms/alg.random.sample/sample.fail.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class PopulationIterator, class SampleIterator, class Distance,
+// class UniformRandomNumberGenerator>
+// SampleIterator sample(PopulationIterator first, PopulationIterator last,
+// SampleIterator out, Distance n,
+// UniformRandomNumberGenerator &&g);
+
+#include <experimental/algorithm>
+#include <random>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <class PopulationIterator, class SampleIterator> void test() {
+ int ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ const unsigned is = sizeof(ia) / sizeof(ia[0]);
+ const unsigned os = 4;
+ int oa[os];
+ std::minstd_rand g;
+ std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is),
+ SampleIterator(oa), os, g);
+}
+
+int main() {
+ test<input_iterator<int *>, output_iterator<int *> >();
+}
diff --git a/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp b/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp
new file mode 100644
index 0000000..0f0784d
--- /dev/null
+++ b/test/std/experimental/algorithms/alg.random.sample/sample.pass.cpp
@@ -0,0 +1,146 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class PopulationIterator, class SampleIterator, class Distance,
+// class UniformRandomNumberGenerator>
+// SampleIterator sample(PopulationIterator first, PopulationIterator last,
+// SampleIterator out, Distance n,
+// UniformRandomNumberGenerator &&g);
+
+#include <experimental/algorithm>
+#include <random>
+#include <cassert>
+
+#include "test_iterators.h"
+
+struct ReservoirSampleExpectations {
+ enum { os = 4 };
+ static int oa1[os];
+ static int oa2[os];
+};
+
+int ReservoirSampleExpectations::oa1[] = {10, 5, 9, 4};
+int ReservoirSampleExpectations::oa2[] = {5, 2, 10, 4};
+
+struct SelectionSampleExpectations {
+ enum { os = 4 };
+ static int oa1[os];
+ static int oa2[os];
+};
+
+int SelectionSampleExpectations::oa1[] = {1, 4, 6, 7};
+int SelectionSampleExpectations::oa2[] = {1, 2, 6, 8};
+
+template <class IteratorCategory> struct TestExpectations
+ : public SelectionSampleExpectations {};
+
+template <>
+struct TestExpectations<std::input_iterator_tag>
+ : public ReservoirSampleExpectations {};
+
+template <template<class> class PopulationIteratorType, class PopulationItem,
+ template<class> class SampleIteratorType, class SampleItem>
+void test() {
+ typedef PopulationIteratorType<PopulationItem *> PopulationIterator;
+ typedef SampleIteratorType<SampleItem *> SampleIterator;
+ PopulationItem ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ const unsigned is = sizeof(ia) / sizeof(ia[0]);
+ typedef TestExpectations<typename std::iterator_traits<
+ PopulationIterator>::iterator_category> Expectations;
+ const unsigned os = Expectations::os;
+ SampleItem oa[os];
+ const int *oa1 = Expectations::oa1;
+ const int *oa2 = Expectations::oa2;
+ std::minstd_rand g;
+ SampleIterator end;
+ end = std::experimental::sample(PopulationIterator(ia),
+ PopulationIterator(ia + is),
+ SampleIterator(oa), os, g);
+ assert(&*end - oa == std::min(os, is));
+ assert(std::equal(oa, oa + os, oa1));
+ end = std::experimental::sample(PopulationIterator(ia),
+ PopulationIterator(ia + is),
+ SampleIterator(oa), os, g);
+ assert(&*end - oa == std::min(os, is));
+ assert(std::equal(oa, oa + os, oa2));
+}
+
+template <template<class> class PopulationIteratorType, class PopulationItem,
+ template<class> class SampleIteratorType, class SampleItem>
+void test_empty_population() {
+ typedef PopulationIteratorType<PopulationItem *> PopulationIterator;
+ typedef SampleIteratorType<SampleItem *> SampleIterator;
+ PopulationItem ia[] = {42};
+ const unsigned os = 4;
+ SampleItem oa[os];
+ std::minstd_rand g;
+ SampleIterator end =
+ std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia),
+ SampleIterator(oa), os, g);
+ assert(&*end == oa);
+}
+
+template <template<class> class PopulationIteratorType, class PopulationItem,
+ template<class> class SampleIteratorType, class SampleItem>
+void test_empty_sample() {
+ typedef PopulationIteratorType<PopulationItem *> PopulationIterator;
+ typedef SampleIteratorType<SampleItem *> SampleIterator;
+ PopulationItem ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ const unsigned is = sizeof(ia) / sizeof(ia[0]);
+ SampleItem oa[1];
+ std::minstd_rand g;
+ SampleIterator end =
+ std::experimental::sample(PopulationIterator(ia), PopulationIterator(ia + is),
+ SampleIterator(oa), 0, g);
+ assert(&*end == oa);
+}
+
+template <template<class> class PopulationIteratorType, class PopulationItem,
+ template<class> class SampleIteratorType, class SampleItem>
+void test_small_population() {
+ // The population size is less than the sample size.
+ typedef PopulationIteratorType<PopulationItem *> PopulationIterator;
+ typedef SampleIteratorType<SampleItem *> SampleIterator;
+ PopulationItem ia[] = {1, 2, 3, 4, 5};
+ const unsigned is = sizeof(ia) / sizeof(ia[0]);
+ const unsigned os = 8;
+ SampleItem oa[os];
+ const SampleItem oa1[] = {1, 2, 3, 4, 5};
+ std::minstd_rand g;
+ SampleIterator end;
+ end = std::experimental::sample(PopulationIterator(ia),
+ PopulationIterator(ia + is),
+ SampleIterator(oa), os, g);
+ assert(&*end - oa == std::min(os, is));
+ assert(std::equal(oa, &*end, oa1));
+}
+
+int main() {
+ test<input_iterator, int, random_access_iterator, int>();
+ test<forward_iterator, int, output_iterator, int>();
+ test<forward_iterator, int, random_access_iterator, int>();
+
+ test<input_iterator, int, random_access_iterator, double>();
+ test<forward_iterator, int, output_iterator, double>();
+ test<forward_iterator, int, random_access_iterator, double>();
+
+ test_empty_population<input_iterator, int, random_access_iterator, int>();
+ test_empty_population<forward_iterator, int, output_iterator, int>();
+ test_empty_population<forward_iterator, int, random_access_iterator, int>();
+
+ test_empty_sample<input_iterator, int, random_access_iterator, int>();
+ test_empty_sample<forward_iterator, int, output_iterator, int>();
+ test_empty_sample<forward_iterator, int, random_access_iterator, int>();
+
+ test_small_population<input_iterator, int, random_access_iterator, int>();
+ test_small_population<forward_iterator, int, output_iterator, int>();
+ test_small_population<forward_iterator, int, random_access_iterator, int>();
+}
diff --git a/test/std/experimental/algorithms/alg.random.sample/sample.stable.pass.cpp b/test/std/experimental/algorithms/alg.random.sample/sample.stable.pass.cpp
new file mode 100644
index 0000000..c805c66
--- /dev/null
+++ b/test/std/experimental/algorithms/alg.random.sample/sample.stable.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class PopulationIterator, class SampleIterator, class Distance,
+// class UniformRandomNumberGenerator>
+// SampleIterator sample(PopulationIterator first, PopulationIterator last,
+// SampleIterator out, Distance n,
+// UniformRandomNumberGenerator &&g);
+
+#include <experimental/algorithm>
+#include <random>
+#include <cassert>
+
+#include "test_iterators.h"
+
+// Stable if and only if PopulationIterator meets the requirements of a
+// ForwardIterator type.
+template <class PopulationIterator, class SampleIterator>
+void test_stability(bool expect_stable) {
+ const unsigned kPopulationSize = 100;
+ int ia[kPopulationSize];
+ for (unsigned i = 0; i < kPopulationSize; ++i)
+ ia[i] = i;
+ PopulationIterator first(ia);
+ PopulationIterator last(ia + kPopulationSize);
+
+ const unsigned kSampleSize = 20;
+ int oa[kPopulationSize];
+ SampleIterator out(oa);
+
+ std::minstd_rand g;
+
+ const int kIterations = 1000;
+ bool unstable = false;
+ for (int i = 0; i < kIterations; ++i) {
+ std::experimental::sample(first, last, out, kSampleSize, g);
+ unstable |= !std::is_sorted(oa, oa + kSampleSize);
+ }
+ assert(expect_stable == !unstable);
+}
+
+int main() {
+ test_stability<forward_iterator<int *>, output_iterator<int *> >(true);
+ test_stability<input_iterator<int *>, random_access_iterator<int *> >(false);
+}
diff --git a/test/std/experimental/algorithms/alg.search/search.pass.cpp b/test/std/experimental/algorithms/alg.search/search.pass.cpp
new file mode 100644
index 0000000..e27f0e4
--- /dev/null
+++ b/test/std/experimental/algorithms/alg.search/search.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template<class ForwardIterator, class Searcher>
+// ForwardIterator search(ForwardIterator first, ForwardIterator last,
+// const Searcher& searcher);
+//
+// returns searcher.operator(first, last)
+//
+
+#include <experimental/algorithm>
+#include <cassert>
+
+#include "test_iterators.h"
+
+int searcher_called = 0;
+
+struct MySearcher {
+ template <typename Iterator>
+ Iterator operator() ( Iterator b, Iterator /*e*/) const
+ {
+ ++searcher_called;
+ return b;
+ }
+};
+
+
+int main() {
+ typedef int * RI;
+ static_assert(std::is_same<RI, decltype(std::experimental::search(RI(), RI(), MySearcher()))>::value, "" );
+
+ RI it{nullptr};
+ assert(it == std::experimental::search(it, it, MySearcher()));
+ assert(searcher_called == 1);
+}
diff --git a/test/std/experimental/any/any.class/any.assign/copy.pass.cpp b/test/std/experimental/any/any.class/any.assign/copy.pass.cpp
new file mode 100644
index 0000000..8ee575c
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.assign/copy.pass.cpp
@@ -0,0 +1,197 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any& operator=(any const &);
+
+// Test copy assignment
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+template <class LHS, class RHS>
+void test_copy_assign() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::copied == 1);
+ assert(LHS::count == 0);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(lhs, 2);
+ assertContains<RHS>(rhs, 2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class LHS>
+void test_copy_assign_empty() {
+ assert(LHS::count == 0);
+ LHS::reset();
+ {
+ any lhs;
+ any const rhs(LHS(42));
+
+ assert(LHS::count == 1);
+ assert(LHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(LHS::copied == 1);
+ assert(LHS::count == 2);
+
+ assertContains<LHS>(lhs, 42);
+ assertContains<LHS>(rhs, 42);
+ }
+ assert(LHS::count == 0);
+ LHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs;
+
+ assert(LHS::count == 1);
+ assert(LHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(LHS::copied == 0);
+ assert(LHS::count == 0);
+
+ assertEmpty<LHS>(lhs);
+ assertEmpty(rhs);
+ }
+ assert(LHS::count == 0);
+}
+
+void test_copy_assign_self() {
+ // empty
+ {
+ any a;
+ a = a;
+ assertEmpty(a);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ // small
+ {
+ any a((small(1)));
+ assert(small::count == 1);
+
+ a = a;
+
+ assert(small::count == 1);
+ assertContains<small>(a, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+ assert(small::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ // large
+ {
+ any a(large(1));
+ assert(large::count == 1);
+
+ a = a;
+
+ assert(large::count == 1);
+ assertContains<large>(a, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ }
+ assert(large::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
+
+template <class Tp>
+void test_copy_assign_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ auto try_throw =
+ [](any& lhs, any const& rhs) {
+ try {
+ lhs = rhs;
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ };
+ // const lvalue to empty
+ {
+ any lhs;
+ any const rhs((Tp(1)));
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(Tp::count == 1);
+ assertEmpty<Tp>(lhs);
+ assertContains<Tp>(rhs);
+ }
+ {
+ any lhs((small(2)));
+ any const rhs((Tp(1)));
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+ assertContains<small>(lhs, 2);
+ assertContains<Tp>(rhs);
+ }
+ {
+ any lhs((large(2)));
+ any const rhs((Tp(1)));
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+ assertContains<large>(lhs, 2);
+ assertContains<Tp>(rhs);
+ }
+#endif
+}
+
+int main() {
+ test_copy_assign<small1, small2>();
+ test_copy_assign<large1, large2>();
+ test_copy_assign<small, large>();
+ test_copy_assign<large, small>();
+ test_copy_assign_empty<small>();
+ test_copy_assign_empty<large>();
+ test_copy_assign_self();
+ test_copy_assign_throws<small_throws_on_copy>();
+ test_copy_assign_throws<large_throws_on_copy>();
+}
diff --git a/test/std/experimental/any/any.class/any.assign/move.pass.cpp b/test/std/experimental/any/any.class/any.assign/move.pass.cpp
new file mode 100644
index 0000000..0a2d719
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.assign/move.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any& operator=(any &&);
+
+// Test move assignment.
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+template <class LHS, class RHS>
+void test_move_assign() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ {
+ LHS const s1(1);
+ any a(s1);
+ RHS const s2(2);
+ any a2(s2);
+
+ assert(LHS::count == 2);
+ assert(RHS::count == 2);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(a, 2);
+ assertEmpty<RHS>(a2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class LHS>
+void test_move_assign_empty() {
+ assert(LHS::count == 0);
+ {
+ any a;
+ any a2((LHS(1)));
+
+ assert(LHS::count == 1);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 1);
+
+ assertContains<LHS>(a, 1);
+ assertEmpty<LHS>(a2);
+ }
+ assert(LHS::count == 0);
+ {
+ any a((LHS(1)));
+ any a2;
+
+ assert(LHS::count == 1);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 0);
+
+ assertEmpty<LHS>(a);
+ assertEmpty(a2);
+ }
+ assert(LHS::count == 0);
+}
+
+void test_move_assign_noexcept() {
+ any a1;
+ any a2;
+ static_assert(
+ noexcept(a1 = std::move(a2))
+ , "any & operator=(any &&) must be noexcept"
+ );
+}
+
+int main() {
+ test_move_assign_noexcept();
+ test_move_assign<small1, small2>();
+ test_move_assign<large1, large2>();
+ test_move_assign<small, large>();
+ test_move_assign<large, small>();
+ test_move_assign_empty<small>();
+ test_move_assign_empty<large>();
+}
diff --git a/test/std/experimental/any/any.class/any.assign/value.pass.cpp b/test/std/experimental/any/any.class/any.assign/value.pass.cpp
new file mode 100644
index 0000000..8262990
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.assign/value.pass.cpp
@@ -0,0 +1,177 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any& operator=(any const &);
+
+// Test value copy and move assignment.
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+template <class LHS, class RHS>
+void test_assign_value() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::copied == 1);
+ assert(LHS::count == 0);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(lhs, 2);
+ assertContains<RHS>(rhs, 2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::moved == 1);
+
+ lhs = std::move(rhs);
+
+ assert(RHS::moved >= 1);
+ assert(RHS::copied == 0);
+ assert(LHS::count == 0);
+ assert(RHS::count == 1);
+
+ assertContains<RHS>(lhs, 2);
+ assertEmpty<RHS>(rhs);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class RHS>
+void test_assign_value_empty() {
+ assert(RHS::count == 0);
+ RHS::reset();
+ {
+ any lhs;
+ RHS rhs(42);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::count == 2);
+ assert(RHS::copied == 1);
+ assert(RHS::moved >= 0);
+ assertContains<RHS>(lhs, 42);
+ }
+ assert(RHS::count == 0);
+ RHS::reset();
+ {
+ any lhs;
+ RHS rhs(42);
+ assert(RHS::count == 1);
+ assert(RHS::moved == 0);
+
+ lhs = std::move(rhs);
+
+ assert(RHS::count == 2);
+ assert(RHS::copied == 0);
+ assert(RHS::moved >= 1);
+ assertContains<RHS>(lhs, 42);
+ }
+ assert(RHS::count == 0);
+ RHS::reset();
+}
+
+
+template <class Tp, bool Move = false>
+void test_assign_throws() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ auto try_throw=
+ [](any& lhs, auto&& rhs) {
+ try {
+ Move ? lhs = std::move(rhs)
+ : lhs = rhs;
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ };
+ // const lvalue to empty
+ {
+ any lhs;
+ Tp rhs(1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(Tp::count == 1);
+ assertEmpty<Tp>(lhs);
+ }
+ {
+ any lhs((small(2)));
+ Tp rhs(1);
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+ assertContains<small>(lhs, 2);
+ }
+ {
+ any lhs((large(2)));
+ Tp rhs(1);
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+ assertContains<large>(lhs, 2);
+ }
+#endif
+}
+
+int main() {
+ test_assign_value<small1, small2>();
+ test_assign_value<large1, large2>();
+ test_assign_value<small, large>();
+ test_assign_value<large, small>();
+ test_assign_value_empty<small>();
+ test_assign_value_empty<large>();
+ test_assign_throws<small_throws_on_copy>();
+ test_assign_throws<large_throws_on_copy>();
+ test_assign_throws<throws_on_move, /* Move = */ true>();
+}
\ No newline at end of file
diff --git a/test/std/experimental/any/any.class/any.assign/value_non_copyable_assign.fail.cpp b/test/std/experimental/any/any.class/any.assign/value_non_copyable_assign.fail.cpp
new file mode 100644
index 0000000..ce0d44f
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.assign/value_non_copyable_assign.fail.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class Value>
+// any& operator=(Value &&);
+
+// Instantiate the value assignment operator with a non-copyable type.
+
+#include <experimental/any>
+
+class non_copyable
+{
+ non_copyable(non_copyable const &);
+
+public:
+ non_copyable() {}
+ non_copyable(non_copyable &&) {}
+};
+
+int main()
+{
+ using namespace std::experimental;
+ non_copyable nc;
+ any a;
+ a = static_cast<non_copyable &&>(nc); // expected-error@experimental/any:* 2 {{static_assert failed "_ValueType must be CopyConstructible."}}
+ // expected-error@experimental/any:* {{calling a private constructor of class 'non_copyable'}}
+
+}
diff --git a/test/std/experimental/any/any.class/any.cons/copy.pass.cpp b/test/std/experimental/any/any.class/any.cons/copy.pass.cpp
new file mode 100644
index 0000000..3d0b34b
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.cons/copy.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any(any const &);
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+template <class Type>
+void test_copy_throws() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(Type::count == 0);
+ {
+ any const a((Type(42)));
+ assert(Type::count == 1);
+ try {
+ any const a2(a);
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(Type::count == 1);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+#endif
+}
+
+void test_copy_empty() {
+ DisableAllocationGuard g; ((void)g); // No allocations should occur.
+ any a1;
+ any a2(a1);
+
+ assertEmpty(a1);
+ assertEmpty(a2);
+}
+
+template <class Type>
+void test_copy()
+{
+ // Copying small types should not perform any allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+
+ any a2(a);
+
+ assert(Type::copied == 1);
+ assert(Type::count == 2);
+ assertContains<Type>(a, 42);
+ assertContains<Type>(a, 42);
+
+ // Modify a and check that a2 is unchanged
+ modifyValue<Type>(a, -1);
+ assertContains<Type>(a, -1);
+ assertContains<Type>(a2, 42);
+
+ // modify a2 and check that a is unchanged
+ modifyValue<Type>(a2, 999);
+ assertContains<Type>(a, -1);
+ assertContains<Type>(a2, 999);
+
+ // clear a and check that a2 is unchanged
+ a.clear();
+ assertEmpty(a);
+ assertContains<Type>(a2, 999);
+ }
+ assert(Type::count == 0);
+}
+
+int main() {
+ test_copy<small>();
+ test_copy<large>();
+ test_copy_empty();
+ test_copy_throws<small_throws_on_copy>();
+ test_copy_throws<large_throws_on_copy>();
+}
diff --git a/test/std/experimental/any/any.class/any.cons/default.pass.cpp b/test/std/experimental/any/any.class/any.cons/default.pass.cpp
new file mode 100644
index 0000000..b52c83f
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.cons/default.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any() noexcept;
+
+#include <experimental/any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+
+
+int main()
+{
+ using std::experimental::any;
+ {
+ static_assert(
+ std::is_nothrow_default_constructible<any>::value
+ , "Must be default constructible"
+ );
+ }
+ {
+ DisableAllocationGuard g; ((void)g);
+ any const a;
+ assertEmpty(a);
+ }
+}
diff --git a/test/std/experimental/any/any.class/any.cons/move.pass.cpp b/test/std/experimental/any/any.class/any.cons/move.pass.cpp
new file mode 100644
index 0000000..40534cb
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.cons/move.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any(any &&) noexcept;
+
+#include <experimental/any>
+#include <utility>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+// Moves are always noexcept. The throws_on_move object
+// must be stored dynamically so the pointer is moved and
+// not the stored object.
+void test_move_does_not_throw()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(throws_on_move::count == 0);
+ {
+ throws_on_move v(42);
+ any a(v);
+ assert(throws_on_move::count == 2);
+ // No allocations should be performed after this point.
+ DisableAllocationGuard g; ((void)g);
+ try {
+ any const a2(std::move(a));
+ assertEmpty(a);
+ assertContains<throws_on_move>(a2, 42);
+ } catch (...) {
+ assert(false);
+ }
+ assert(throws_on_move::count == 1);
+ assertEmpty(a);
+ }
+ assert(throws_on_move::count == 0);
+#endif
+}
+
+void test_move_empty() {
+ DisableAllocationGuard g; ((void)g); // no allocations should be performed.
+
+ any a1;
+ any a2(std::move(a1));
+
+ assertEmpty(a1);
+ assertEmpty(a2);
+}
+
+template <class Type>
+void test_move() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Moving should not perform allocations since it must be noexcept.
+ DisableAllocationGuard g; ((void)g);
+
+ any a2(std::move(a));
+
+ assert(Type::moved >= 1); // zero or more move operations can be performed.
+ assert(Type::copied == 0); // no copies can be performed.
+ assert(Type::count == 1);
+ assertEmpty(a); // Moves are always destructive.
+ assertContains<Type>(a2, 42);
+ }
+ assert(Type::count == 0);
+}
+
+int main()
+{
+ // noexcept test
+ {
+ static_assert(
+ std::is_nothrow_move_constructible<any>::value
+ , "any must be nothrow move constructible"
+ );
+ }
+ test_move<small>();
+ test_move<large>();
+ test_move_empty();
+ test_move_does_not_throw();
+}
diff --git a/test/std/experimental/any/any.class/any.cons/non_copyable_value.fail.cpp b/test/std/experimental/any/any.class/any.cons/non_copyable_value.fail.cpp
new file mode 100644
index 0000000..643b962
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.cons/non_copyable_value.fail.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any::any<Value>(Value &&)
+
+// Attempt to construct any with a non-copyable type.
+
+#include <experimental/any>
+
+class non_copyable
+{
+ non_copyable(non_copyable const &);
+
+public:
+ non_copyable() {}
+ non_copyable(non_copyable &&) {}
+};
+
+int main()
+{
+ using namespace std::experimental;
+ non_copyable nc;
+ any a(static_cast<non_copyable &&>(nc));
+ // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType must be CopyConstructible."}}
+ // expected-error@experimental/any:* 1 {{calling a private constructor of class 'non_copyable'}}
+}
diff --git a/test/std/experimental/any/any.class/any.cons/value.pass.cpp b/test/std/experimental/any/any.class/any.cons/value.pass.cpp
new file mode 100644
index 0000000..7bb134e
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.cons/value.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class Value> any(Value &&)
+
+// Test construction from a value.
+// Concerns:
+// ---------
+// 1. The value is properly move/copied depending on the value category.
+// 2. Both small and large values are properly handled.
+
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+template <class Type>
+void test_copy_value_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(Type::count == 0);
+ {
+ Type const t(42);
+ assert(Type::count == 1);
+ try {
+ any const a2(t);
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(Type::count == 1);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 0);
+#endif
+}
+
+void test_move_value_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(throws_on_move::count == 0);
+ {
+ throws_on_move v;
+ assert(throws_on_move::count == 1);
+ try {
+ any const a(std::move(v));
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(throws_on_move::count == 1);
+ }
+ assert(throws_on_move::count == 0);
+#endif
+}
+
+template <class Type>
+void test_copy_move_value() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ Type t(42);
+ assert(Type::count == 1);
+
+ any a(t);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ Type t(42);
+ assert(Type::count == 1);
+
+ any a(std::move(t));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ assertContains<Type>(a, 42);
+ }
+}
+
+
+int main() {
+ test_copy_move_value<small>();
+ test_copy_move_value<large>();
+ test_copy_value_throws<small_throws_on_copy>();
+ test_copy_value_throws<large_throws_on_copy>();
+ test_move_value_throws();
+}
\ No newline at end of file
diff --git a/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp b/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp
new file mode 100644
index 0000000..603490c
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any::clear() noexcept
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+int main()
+{
+ using std::experimental::any;
+ using std::experimental::any_cast;
+ // empty
+ {
+ any a;
+
+ // noexcept check
+ static_assert(
+ noexcept(a.clear())
+ , "any.clear() must be noexcept"
+ );
+
+ assertEmpty(a);
+
+ a.clear();
+
+ assertEmpty(a);
+ }
+ // small object
+ {
+ any a((small(1)));
+ assert(small::count == 1);
+ assertContains<small>(a, 1);
+
+ a.clear();
+
+ assertEmpty<small>(a);
+ assert(small::count == 0);
+ }
+ // large object
+ {
+ any a(large(1));
+ assert(large::count == 1);
+ assertContains<large>(a);
+
+ a.clear();
+
+ assertEmpty<large>(a);
+ assert(large::count == 0);
+ }
+}
diff --git a/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp b/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp
new file mode 100644
index 0000000..0649351
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any::swap(any &) noexcept
+
+// Test swap(large, small) and swap(small, large)
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+template <class LHS, class RHS>
+void test_swap() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ {
+ any a1((LHS(1)));
+ any a2(RHS{2});
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+
+ a1.swap(a2);
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+
+ assertContains<RHS>(a1, 2);
+ assertContains<LHS>(a2, 1);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ assert(LHS::copied == 0);
+ assert(RHS::copied == 0);
+}
+
+template <class Tp>
+void test_swap_empty() {
+ assert(Tp::count == 0);
+ {
+ any a1((Tp(1)));
+ any a2;
+ assert(Tp::count == 1);
+
+ a1.swap(a2);
+
+ assert(Tp::count == 1);
+
+ assertContains<Tp>(a2, 1);
+ assertEmpty(a1);
+ }
+ assert(Tp::count == 0);
+ {
+ any a1((Tp(1)));
+ any a2;
+ assert(Tp::count == 1);
+
+ a2.swap(a1);
+
+ assert(Tp::count == 1);
+
+ assertContains<Tp>(a2, 1);
+ assertEmpty(a1);
+ }
+ assert(Tp::count == 0);
+ assert(Tp::copied == 0);
+}
+
+void test_noexcept()
+{
+ any a1;
+ any a2;
+ static_assert(
+ noexcept(a1.swap(a2))
+ , "any::swap(any&) must be noexcept"
+ );
+}
+
+int main()
+{
+ test_noexcept();
+ test_swap_empty<small>();
+ test_swap_empty<large>();
+ test_swap<small1, small2>();
+ test_swap<large1, large2>();
+ test_swap<small, large>();
+ test_swap<large, small>();
+}
diff --git a/test/std/experimental/any/any.class/any.observers/empty.pass.cpp b/test/std/experimental/any/any.class/any.observers/empty.pass.cpp
new file mode 100644
index 0000000..8c681f3
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.observers/empty.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// any::empty() noexcept
+
+#include <experimental/any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+int main()
+{
+ using std::experimental::any;
+ // noexcept test
+ {
+ any a;
+ static_assert(noexcept(a.empty()), "any::empty() must be noexcept");
+ }
+ // empty
+ {
+ any a;
+ assert(a.empty());
+
+ a.clear();
+ assert(a.empty());
+
+ a = 42;
+ assert(!a.empty());
+ }
+ // small object
+ {
+ small const s(1);
+ any a(s);
+ assert(!a.empty());
+
+ a.clear();
+ assert(a.empty());
+
+ a = s;
+ assert(!a.empty());
+ }
+ // large object
+ {
+ large const l(1);
+ any a(l);
+ assert(!a.empty());
+
+ a.clear();
+ assert(a.empty());
+
+ a = l;
+ assert(!a.empty());
+ }
+}
diff --git a/test/std/experimental/any/any.class/any.observers/type.pass.cpp b/test/std/experimental/any/any.class/any.observers/type.pass.cpp
new file mode 100644
index 0000000..682b73b
--- /dev/null
+++ b/test/std/experimental/any/any.class/any.observers/type.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// XFAIL: libcpp-no-rtti
+
+// <experimental/any>
+
+// any::type() noexcept
+
+#include <experimental/any>
+#include <cassert>
+#include "any_helpers.h"
+
+int main()
+{
+ using std::experimental::any;
+ {
+ any const a;
+ assert(a.type() == typeid(void));
+ static_assert(noexcept(a.type()), "any::type() must be noexcept");
+ }
+ {
+ small const s(1);
+ any const a(s);
+ assert(a.type() == typeid(small));
+
+ }
+ {
+ large const l(1);
+ any const a(l);
+ assert(a.type() == typeid(large));
+ }
+}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/experimental/any/any.class/nothing_to_do.pass.cpp
similarity index 86%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/experimental/any/any.class/nothing_to_do.pass.cpp
index b58f5c5..c21f8a7 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/experimental/any/any.class/nothing_to_do.pass.cpp
@@ -7,6 +7,6 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
-}
+#include <experimental/string_view>
+
+int main () {}
diff --git a/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp b/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
new file mode 100644
index 0000000..9d9a5cd
--- /dev/null
+++ b/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
@@ -0,0 +1,146 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class ValueType>
+// ValueType const* any_cast(any const *) noexcept;
+//
+// template <class ValueType>
+// ValueType * any_cast(any *) noexcept;
+
+#include <experimental/any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+// Test that the operators are properly noexcept.
+void test_cast_is_noexcept() {
+ any a;
+ static_assert(noexcept(any_cast<int>(&a)), "");
+
+ any const& ca = a;
+ static_assert(noexcept(any_cast<int>(&ca)), "");
+}
+
+// Test that the return type of any_cast is correct.
+void test_cast_return_type() {
+ any a;
+ static_assert(std::is_same<decltype(any_cast<int>(&a)), int*>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(&a)), int const*>::value, "");
+
+ any const& ca = a;
+ static_assert(std::is_same<decltype(any_cast<int>(&ca)), int const*>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(&ca)), int const*>::value, "");
+}
+
+// Test that any_cast handles null pointers.
+void test_cast_nullptr() {
+ any* a = nullptr;
+ assert(nullptr == any_cast<int>(a));
+ assert(nullptr == any_cast<int const>(a));
+
+ any const* ca = nullptr;
+ assert(nullptr == any_cast<int>(ca));
+ assert(nullptr == any_cast<int const>(ca));
+}
+
+// Test casting an empty object.
+void test_cast_empty() {
+ {
+ any a;
+ assert(nullptr == any_cast<int>(&a));
+ assert(nullptr == any_cast<int const>(&a));
+
+ any const& ca = a;
+ assert(nullptr == any_cast<int>(&ca));
+ assert(nullptr == any_cast<int const>(&ca));
+ }
+ // Create as non-empty, then make empty and run test.
+ {
+ any a(42);
+ a.clear();
+ assert(nullptr == any_cast<int>(&a));
+ assert(nullptr == any_cast<int const>(&a));
+
+ any const& ca = a;
+ assert(nullptr == any_cast<int>(&ca));
+ assert(nullptr == any_cast<int const>(&ca));
+ }
+}
+
+template <class Type>
+void test_cast() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ assert(any_cast<int>(&a) == nullptr);
+ assert(any_cast<int const>(&a) == nullptr);
+ assert(any_cast<int const volatile>(&a) == nullptr);
+
+ // Try a cast to the right type, but as a pointer.
+ assert(any_cast<Type*>(&a) == nullptr);
+ assert(any_cast<Type const*>(&a) == nullptr);
+
+ // Check getting a unqualified type from a non-const any.
+ Type* v = any_cast<Type>(&a);
+ assert(v != nullptr);
+ assert(v->value == 42);
+
+ // change the stored value and later check for the new value.
+ v->value = 999;
+
+ // Check getting a const qualified type from a non-const any.
+ Type const* cv = any_cast<Type const>(&a);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a unqualified type from a const any.
+ cv = any_cast<Type>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a const-qualified type from a const any.
+ cv = any_cast<Type const>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check that no more objects were created, copied or moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
+}
+
+int main() {
+ test_cast_is_noexcept();
+ test_cast_return_type();
+ test_cast_nullptr();
+ test_cast_empty();
+ test_cast<small>();
+ test_cast<large>();
+}
diff --git a/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp b/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
new file mode 100644
index 0000000..e975609
--- /dev/null
+++ b/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
@@ -0,0 +1,309 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class ValueType>
+// ValueType const any_cast(any const&);
+//
+// template <class ValueType>
+// ValueType any_cast(any &);
+//
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+#include <experimental/any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::experimental::any;
+using std::experimental::any_cast;
+using std::experimental::bad_any_cast;
+
+
+// Test that the operators are NOT marked noexcept.
+void test_cast_is_not_noexcept() {
+ any a;
+ static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
+ static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
+ static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
+}
+
+// Test that the return type of any_cast is correct.
+void test_cast_return_type() {
+ any a;
+ static_assert(std::is_same<decltype(any_cast<int>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
+
+ //static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
+ //static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
+
+ //static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
+ //static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
+
+ any const& ca = a;
+ static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
+
+ //static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
+}
+
+template <class Type, class ConstT = Type>
+void checkThrows(any& a)
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ try {
+ any_cast<Type>(a);
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ any_cast<ConstT>(static_cast<any const&>(a));
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ any_cast<Type>(static_cast<any&&>(a));
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+#endif
+}
+
+void test_cast_empty() {
+ // None of these operations should allocate.
+ DisableAllocationGuard g; ((void)g);
+ any a;
+ checkThrows<int>(a);
+}
+
+template <class Type>
+void test_cast_to_reference() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ // Check getting a type by reference from a non-const lvalue any.
+ {
+ Type& v = any_cast<Type&>(a);
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(a);
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const lvalue any.
+ {
+ Type const& v = any_cast<Type const&>(ca);
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(ca);
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a non-const rvalue
+ {
+ Type& v = any_cast<Type&>(std::move(a));
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(std::move(a));
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type const& v = any_cast<Type const&>(std::move(ca));
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(std::move(ca));
+ assert(&cv == &v);
+ }
+
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+
+ // Check that no objects have been created/copied/moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
+}
+
+template <class Type>
+void test_cast_to_value() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ Type::reset(); // NOTE: reset does not modify Type::count
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type const>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any const&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const rvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any &&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type const>(static_cast<any &&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any const&&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ // Ensure we still only have 1 Type object alive.
+ assert(Type::count == 1);
+
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+}
+
+// Even though you can't get a non-copyable class into std::any
+// the standard requires that these overloads compile and function.
+void test_non_copyable_ref() {
+ struct no_copy
+ {
+ no_copy() {}
+ no_copy(no_copy &&) {}
+ private:
+ no_copy(no_copy const &);
+ };
+
+ any a;
+ checkThrows<no_copy &, no_copy const&>(a);
+ checkThrows<no_copy const&>(a);
+ assertEmpty(a);
+}
+
+int main() {
+ test_cast_is_not_noexcept();
+ test_cast_return_type();
+ test_cast_empty();
+ test_cast_to_reference<small>();
+ test_cast_to_reference<large>();
+ test_cast_to_value<small>();
+ test_cast_to_value<large>();
+ test_non_copyable_ref();
+}
diff --git a/test/std/experimental/any/any.nonmembers/any.cast/const_correctness.fail.cpp b/test/std/experimental/any/any.nonmembers/any.cast/const_correctness.fail.cpp
new file mode 100644
index 0000000..db51492
--- /dev/null
+++ b/test/std/experimental/any/any.nonmembers/any.cast/const_correctness.fail.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class ValueType>
+// ValueType any_cast(any const &);
+
+// Try and cast away const.
+
+#include <experimental/any>
+
+struct TestType {};
+struct TestType2 {};
+
+int main()
+{
+ using std::experimental::any;
+ using std::experimental::any_cast;
+
+ any a;
+
+ // expected-error@experimental/any:* 2 {{binding value of type '_Tp' (aka 'const TestType') to reference to type 'TestType' drops 'const' qualifier}}
+ any_cast<TestType &>(static_cast<any const&>(a)); // expected-note {{requested here}}
+ any_cast<TestType &&>(static_cast<any const&>(a)); // expected-note {{requested here}}
+
+ // expected-error@experimental/any:* 2 {{binding value of type '_Tp' (aka 'const TestType2') to reference to type 'TestType2' drops 'const' qualifier}}
+ any_cast<TestType2 &>(static_cast<any const&&>(a)); // expected-note {{requested here}}
+ any_cast<TestType2 &&>(static_cast<any const&&>(a)); // expected-note {{requested here}}
+}
diff --git a/test/std/experimental/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp b/test/std/experimental/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
new file mode 100644
index 0000000..c6cc68d
--- /dev/null
+++ b/test/std/experimental/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class ValueType>
+// ValueType const any_cast(any const&);
+//
+// template <class ValueType>
+// ValueType any_cast(any &);
+//
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+// Test instantiating the any_cast with a non-copyable type.
+
+#include <experimental/any>
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+struct no_copy
+{
+ no_copy() {}
+ no_copy(no_copy &&) {}
+private:
+ no_copy(no_copy const &);
+};
+
+int main() {
+ any a;
+ any_cast<no_copy>(static_cast<any&>(a));
+ any_cast<no_copy>(static_cast<any const&>(a));
+ any_cast<no_copy>(static_cast<any &&>(a));
+ // expected-error@experimental/any:* 3 {{static_assert failed "_ValueType is required to be a reference or a CopyConstructible type."}}
+ // expected-error@experimental/any:* 3 {{calling a private constructor of class 'no_copy'}}
+}
\ No newline at end of file
diff --git a/test/std/experimental/any/any.nonmembers/any.cast/reference_types.fail.cpp b/test/std/experimental/any/any.nonmembers/any.cast/reference_types.fail.cpp
new file mode 100644
index 0000000..6c6ccc6
--- /dev/null
+++ b/test/std/experimental/any/any.nonmembers/any.cast/reference_types.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// template <class ValueType>
+// ValueType const* any_cast(any const *) noexcept;
+//
+// template <class ValueType>
+// ValueType * any_cast(any *) noexcept;
+
+#include <experimental/any>
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+int main()
+{
+ any a(1);
+ any_cast<int &>(&a); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int &&>(&a); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &>(&a); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const&&>(&a); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any const& a2 = a;
+ any_cast<int &>(&a2); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int &&>(&a2); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &>(&a2); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &&>(&a2); // expected-error@experimental/any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+}
diff --git a/test/std/experimental/any/any.nonmembers/swap.pass.cpp b/test/std/experimental/any/any.nonmembers/swap.pass.cpp
new file mode 100644
index 0000000..a3fbd43
--- /dev/null
+++ b/test/std/experimental/any/any.nonmembers/swap.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/any>
+
+// void swap(any &, any &) noexcept
+
+// swap(...) just wraps any::swap(...). That function is tested elsewhere.
+
+#include <experimental/any>
+#include <cassert>
+
+using std::experimental::any;
+using std::experimental::any_cast;
+
+int main()
+{
+
+ { // test noexcept
+ any a;
+ static_assert(noexcept(swap(a, a)), "swap(any&, any&) must be noexcept");
+ }
+ {
+ any a1(1);
+ any a2(2);
+
+ swap(a1, a2);
+
+ assert(any_cast<int>(a1) == 2);
+ assert(any_cast<int>(a2) == 1);
+ }
+}
diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp
new file mode 100644
index 0000000..446dcbd
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.default/default.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// default searcher
+// template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+// class default_searcher {
+// public:
+// default_searcher(_ForwardIterator __f, _ForwardIterator __l,
+// _BinaryPredicate __p = _BinaryPredicate())
+// : __first_(__f), __last_(__l), __pred_(__p) {}
+//
+// template <typename _ForwardIterator2>
+// _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const {
+// return std::search(__f, __l, __first_, __last_, __pred_);
+// }
+//
+// private:
+// _ForwardIterator __first_;
+// _ForwardIterator __last_;
+// _BinaryPredicate __pred_;
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result) {
+ std::experimental::default_searcher<Iter2> s{b2, e2};
+ assert(result == std::experimental::search(b1, e1, s));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+ int ia[] = {0, 1, 2, 3, 4, 5};
+ const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+1), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+1), Iter2(ia+2), Iter1(ia+1));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+2), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2));
+ do_search(Iter1(ia), Iter1(ia), Iter2(ia+2), Iter2(ia+3), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia), Iter2(ia+sa), Iter1(ia+sa-1));
+ do_search(Iter1(ia), Iter1(ia+1), Iter2(ia), Iter2(ia+sa), Iter1(ia+1));
+ int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+ int ic[] = {1};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1));
+ int id[] = {1, 2};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1));
+ int ie[] = {1, 2, 3};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4));
+ int ig[] = {1, 2, 3, 4};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8));
+ int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+ int ii[] = {1, 1, 2};
+ do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3));
+ int ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+ const unsigned sj = sizeof(ij)/sizeof(ij[0]);
+ int ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+ const unsigned sk = sizeof(ik)/sizeof(ik[0]);
+ do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
+}
+
+int main() {
+ test<forward_iterator<const int*>, forward_iterator<const int*> >();
+ test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<forward_iterator<const int*>, random_access_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();
+ test<random_access_iterator<const int*>, forward_iterator<const int*> >();
+ test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+}
diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp
new file mode 100644
index 0000000..b65c500
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.default/default.pred.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// default searcher
+// template<class _ForwardIterator, class _BinaryPredicate = equal_to<>>
+// class default_searcher {
+// public:
+// default_searcher(_ForwardIterator __f, _ForwardIterator __l,
+// _BinaryPredicate __p = _BinaryPredicate())
+// : __first_(__f), __last_(__l), __pred_(__p) {}
+//
+// template <typename _ForwardIterator2>
+// _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const {
+// return std::search(__f, __l, __first_, __last_, __pred_);
+// }
+//
+// private:
+// _ForwardIterator __first_;
+// _ForwardIterator __last_;
+// _BinaryPredicate __pred_;
+// };
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+struct count_equal
+{
+ static unsigned count;
+ template <class T>
+ bool operator()(const T& x, const T& y) const
+ {++count; return x == y;}
+};
+
+unsigned count_equal::count = 0;
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) {
+ std::experimental::default_searcher<Iter2, count_equal> s{b2, e2};
+ count_equal::count = 0;
+ assert(result == std::experimental::search(b1, e1, s));
+ assert(count_equal::count <= max_count);
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+ int ia[] = {0, 1, 2, 3, 4, 5};
+ const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia), Iter1(ia), 0);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+1), Iter1(ia), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+1), Iter2(ia+2), Iter1(ia+1), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+2), Iter1(ia), 0);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2), sa);
+ do_search(Iter1(ia), Iter1(ia), Iter2(ia+2), Iter2(ia+3), Iter1(ia), 0);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), Iter1(ia), sa*sa);
+ do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia), Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+ do_search(Iter1(ia), Iter1(ia+1), Iter2(ia), Iter2(ia+sa), Iter1(ia+1), sa);
+ int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+ int ic[] = {1};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+ int id[] = {1, 2};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+ int ie[] = {1, 2, 3};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+ int ig[] = {1, 2, 3, 4};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+ int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+ int ii[] = {1, 1, 2};
+ do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3), sh*3);
+}
+
+int main() {
+ test<forward_iterator<const int*>, forward_iterator<const int*> >();
+ test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<forward_iterator<const int*>, random_access_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();
+ test<random_access_iterator<const int*>, forward_iterator<const int*> >();
+ test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+}
diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp
new file mode 100644
index 0000000..9528002
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// template<class ForwardIterator, class BinaryPredicate = equal_to<>>
+// default_searcher<ForwardIterator, BinaryPredicate>
+// make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
+// BinaryPredicate pred = BinaryPredicate());
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result) {
+ assert(result == std::experimental::search(b1, e1,
+ std::experimental::make_default_searcher(b2, e2)));
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+ int ia[] = {0, 1, 2, 3, 4, 5};
+ const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+1), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+1), Iter2(ia+2), Iter1(ia+1));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+2), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2));
+ do_search(Iter1(ia), Iter1(ia), Iter2(ia+2), Iter2(ia+3), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3));
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), Iter1(ia));
+ do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia), Iter2(ia+sa), Iter1(ia+sa-1));
+ do_search(Iter1(ia), Iter1(ia+1), Iter2(ia), Iter2(ia+sa), Iter1(ia+1));
+ int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+ int ic[] = {1};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1));
+ int id[] = {1, 2};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1));
+ int ie[] = {1, 2, 3};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4));
+ int ig[] = {1, 2, 3, 4};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8));
+ int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+ int ii[] = {1, 1, 2};
+ do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3));
+ int ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+ const unsigned sj = sizeof(ij)/sizeof(ij[0]);
+ int ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};
+ const unsigned sk = sizeof(ik)/sizeof(ik[0]);
+ do_search(Iter1(ij), Iter1(ij+sj), Iter2(ik), Iter2(ik+sk), Iter1(ij+6));
+}
+
+int main() {
+ test<forward_iterator<const int*>, forward_iterator<const int*> >();
+ test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<forward_iterator<const int*>, random_access_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();
+ test<random_access_iterator<const int*>, forward_iterator<const int*> >();
+ test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+}
diff --git a/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp
new file mode 100644
index 0000000..2770202
--- /dev/null
+++ b/test/std/experimental/func/func.searchers/func.searchers.default/func.searchers.default.creation/make_default_searcher.pred.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <functional>
+
+// template<class ForwardIterator, class BinaryPredicate = equal_to<>>
+// default_searcher<ForwardIterator, BinaryPredicate>
+// make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
+// BinaryPredicate pred = BinaryPredicate());
+
+
+#include <experimental/algorithm>
+#include <experimental/functional>
+#include <cassert>
+
+#include "test_iterators.h"
+
+struct count_equal
+{
+ static unsigned count;
+ template <class T>
+ bool operator()(const T& x, const T& y)
+ {++count; return x == y;}
+};
+
+unsigned count_equal::count = 0;
+
+template <typename Iter1, typename Iter2>
+void do_search(Iter1 b1, Iter1 e1, Iter2 b2, Iter2 e2, Iter1 result, unsigned max_count) {
+ count_equal::count = 0;
+ assert(result == std::experimental::search(b1, e1,
+ std::experimental::make_default_searcher(b2, e2)));
+ assert(count_equal::count <= max_count);
+}
+
+template <class Iter1, class Iter2>
+void
+test()
+{
+ int ia[] = {0, 1, 2, 3, 4, 5};
+ const unsigned sa = sizeof(ia)/sizeof(ia[0]);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia), Iter1(ia), 0);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+1), Iter1(ia), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+1), Iter2(ia+2), Iter1(ia+1), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+2), Iter1(ia), 0);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+2), Iter2(ia+3), Iter1(ia+2), sa);
+ do_search(Iter1(ia), Iter1(ia), Iter2(ia+2), Iter2(ia+3), Iter1(ia), 0);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-1), Iter2(ia+sa), Iter1(ia+sa-1), sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia+sa-3), Iter2(ia+sa), Iter1(ia+sa-3), 3*sa);
+ do_search(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), Iter1(ia), sa*sa);
+ do_search(Iter1(ia), Iter1(ia+sa-1), Iter2(ia), Iter2(ia+sa), Iter1(ia+sa-1), (sa-1)*sa);
+ do_search(Iter1(ia), Iter1(ia+1), Iter2(ia), Iter2(ia+sa), Iter1(ia+1), sa);
+ int ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sb = sizeof(ib)/sizeof(ib[0]);
+ int ic[] = {1};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ic), Iter2(ic+1), Iter1(ib+1), sb);
+ int id[] = {1, 2};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(id), Iter2(id+2), Iter1(ib+1), sb*2);
+ int ie[] = {1, 2, 3};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ie), Iter2(ie+3), Iter1(ib+4), sb*3);
+ int ig[] = {1, 2, 3, 4};
+ do_search(Iter1(ib), Iter1(ib+sb), Iter2(ig), Iter2(ig+4), Iter1(ib+8), sb*4);
+ int ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};
+ const unsigned sh = sizeof(ih)/sizeof(ih[0]);
+ int ii[] = {1, 1, 2};
+ do_search(Iter1(ih), Iter1(ih+sh), Iter2(ii), Iter2(ii+3), Iter1(ih+3), sh*3);
+}
+
+int main() {
+ test<forward_iterator<const int*>, forward_iterator<const int*> >();
+ test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<forward_iterator<const int*>, random_access_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, forward_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();
+ test<random_access_iterator<const int*>, forward_iterator<const int*> >();
+ test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();
+ test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
+}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/experimental/func/func.searchers/nothing_to_do.pass.cpp
similarity index 95%
rename from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
rename to test/std/experimental/func/func.searchers/nothing_to_do.pass.cpp
index b58f5c5..9a59227 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/experimental/func/func.searchers/nothing_to_do.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/experimental/func/header.functional.synop/includes.pass.cpp
similarity index 68%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/experimental/func/header.functional.synop/includes.pass.cpp
index b58f5c5..1b72d4a 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/experimental/func/header.functional.synop/includes.pass.cpp
@@ -7,6 +7,15 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/functional>
+//
+// has to include <functional>
+
+#include <experimental/functional>
+
int main()
{
+ std::function<int(int)> x;
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/experimental/func/nothing_to_do.pass.cpp
similarity index 95%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/experimental/func/nothing_to_do.pass.cpp
index b58f5c5..9a59227 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/experimental/func/nothing_to_do.pass.cpp
@@ -1,3 +1,4 @@
+// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
similarity index 75%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
index b58f5c5..d37557a 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/experimental/utilities/tuple/header.tuple.synop/includes.pass.cpp
@@ -7,6 +7,13 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+#include <experimental/tuple>
+
int main()
{
+ std::tuple<int> x(1);
}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp
new file mode 100644
index 0000000..56dc3c6
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/arg_type.pass.cpp
@@ -0,0 +1,182 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Test with different ref/ptr/cv qualified argument types.
+
+#include <experimental/tuple>
+#include <array>
+#include <utility>
+#include <cassert>
+
+namespace ex = std::experimental;
+
+int call_with_value(int x, int y) { return (x + y); }
+int call_with_ref(int & x, int & y) { return (x + y); }
+int call_with_const_ref(int const & x, int const & y) { return (x + y); }
+int call_with_rvalue_ref(int && x, int && y) { return (x + y); }
+int call_with_pointer(int * x, int * y) { return (*x + *y); }
+int call_with_const_pointer(int const* x, int const * y) { return (*x + *y); }
+
+
+template <class Tuple>
+void test_values()
+{
+ {
+ Tuple t{1, 2};
+ assert(3 == ex::apply(call_with_value, t));
+ }
+ {
+ Tuple t{2, 2};
+ assert(4 == ex::apply(call_with_ref, t));
+ }
+ {
+ Tuple t{2, 3};
+ assert(5 == ex::apply(call_with_const_ref, t));
+ }
+ {
+ Tuple t{3, 3};
+ assert(6 == ex::apply(call_with_rvalue_ref, static_cast<Tuple &&>(t)));
+ }
+ {
+ Tuple const t{4, 4};
+ assert(8 == ex::apply(call_with_value, t));
+ }
+ {
+ Tuple const t{4, 5};
+ assert(9 == ex::apply(call_with_const_ref, t));
+ }
+}
+
+template <class Tuple>
+void test_refs()
+{
+ int x = 0;
+ int y = 0;
+ {
+ x = 1; y = 2;
+ Tuple t{x, y};
+ assert(3 == ex::apply(call_with_value, t));
+ }
+ {
+ x = 2; y = 2;
+ Tuple t{x, y};
+ assert(4 == ex::apply(call_with_ref, t));
+ }
+ {
+ x = 2; y = 3;
+ Tuple t{x, y};
+ assert(5 == ex::apply(call_with_const_ref, t));
+ }
+ {
+ x = 3; y = 3;
+ Tuple const t{x, y};
+ assert(6 == ex::apply(call_with_value, t));
+ }
+ {
+ x = 3; y = 4;
+ Tuple const t{x, y};
+ assert(7 == ex::apply(call_with_const_ref, t));
+ }
+}
+
+template <class Tuple>
+void test_const_refs()
+{
+ int x = 0;
+ int y = 0;
+ {
+ x = 1; y = 2;
+ Tuple t{x, y};
+ assert(3 == ex::apply(call_with_value, t));
+ }
+ {
+ x = 2; y = 3;
+ Tuple t{x, y};
+ assert(5 == ex::apply(call_with_const_ref, t));
+ }
+ {
+ x = 3; y = 3;
+ Tuple const t{x, y};
+ assert(6 == ex::apply(call_with_value, t));
+ }
+ {
+ x = 3; y = 4;
+ Tuple const t{x, y};
+ assert(7 == ex::apply(call_with_const_ref, t));
+ }
+}
+
+
+template <class Tuple>
+void test_pointer()
+{
+ int x = 0;
+ int y = 0;
+ {
+ x = 2; y = 2;
+ Tuple t{&x, &y};
+ assert(4 == ex::apply(call_with_pointer, t));
+ }
+ {
+ x = 2; y = 3;
+ Tuple t{&x, &y};
+ assert(5 == ex::apply(call_with_const_pointer, t));
+ }
+ {
+ x = 3; y = 4;
+ Tuple const t{&x, &y};
+ assert(7 == ex::apply(call_with_const_pointer, t));
+ }
+}
+
+
+template <class Tuple>
+void test_const_pointer()
+{
+ int x = 0;
+ int y = 0;
+ {
+ x = 2; y = 3;
+ Tuple t{&x, &y};
+ assert(5 == ex::apply(call_with_const_pointer, t));
+ }
+ {
+ x = 3; y = 4;
+ Tuple const t{&x, &y};
+ assert(7 == ex::apply(call_with_const_pointer, t));
+ }
+}
+
+
+int main()
+{
+ test_values<std::tuple<int, int>>();
+ test_values<std::pair<int, int>>();
+ test_values<std::array<int, 2>>();
+
+ test_refs<std::tuple<int &, int &>>();
+ test_refs<std::pair<int &, int &>>();
+
+ test_const_refs<std::tuple<int const &, int const &>>();
+ test_const_refs<std::pair<int const &, int const &>>();
+
+ test_pointer<std::tuple<int *, int *>>();
+ test_pointer<std::pair<int *, int *>>();
+ test_pointer<std::array<int *, 2>>();
+
+ test_const_pointer<std::tuple<int const *, int const *>>();
+ test_const_pointer<std::pair<int const *, int const *>>();
+ test_const_pointer<std::array<int const *, 2>>();
+}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp
new file mode 100644
index 0000000..2d70048
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// TODO(ericwf)
+// constexpr support temporarily reverted due to bug:
+// https://llvm.org/bugs/show_bug.cgi?id=23141
+// XFAIL: *
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Testing constexpr evaluation
+
+#include <experimental/tuple>
+#include <utility>
+#include <cassert>
+
+constexpr int f_int_0() { return 1; }
+constexpr int f_int_1(int x) { return x; }
+constexpr int f_int_2(int x, int y) { return (x + y); }
+
+struct A_int_0
+{
+ constexpr A_int_0() {}
+ constexpr int operator()() const { return 1; }
+};
+
+struct A_int_1
+{
+ constexpr A_int_1() {}
+ constexpr int operator()(int x) const { return x; }
+};
+
+struct A_int_2
+{
+ constexpr A_int_2() {}
+ constexpr int operator()(int x, int y) const { return (x + y); }
+};
+
+namespace ex = std::experimental;
+
+template <class Tuple>
+void test_0()
+{
+ // function
+ {
+ constexpr Tuple t{};
+ static_assert(1 == ex::apply(f_int_0, t), "");
+ }
+ // function pointer
+ {
+ constexpr Tuple t{};
+ constexpr auto fp = &f_int_0;
+ static_assert(1 == ex::apply(fp, t), "");
+ }
+ // functor
+ {
+ constexpr Tuple t{};
+ constexpr A_int_0 a;
+ static_assert(1 == ex::apply(a, t), "");
+ }
+}
+
+template <class Tuple>
+void test_1()
+{
+ // function
+ {
+ constexpr Tuple t{1};
+ static_assert(1 == ex::apply(f_int_1, t), "");
+ }
+ // function pointer
+ {
+ constexpr Tuple t{2};
+ constexpr int (*fp)(int) = f_int_1;
+ static_assert(2 == ex::apply(fp, t), "");
+ }
+ // functor
+ {
+ constexpr Tuple t{3};
+ constexpr A_int_1 fn;
+ static_assert(3 == ex::apply(fn, t), "");
+ }
+}
+
+template <class Tuple>
+void test_2()
+{
+ // function
+ {
+ constexpr Tuple t{1, 2};
+ static_assert(3 == ex::apply(f_int_2, t), "");
+ }
+ // function pointer
+ {
+ constexpr Tuple t{2, 3};
+ constexpr auto fp = &f_int_2;
+ static_assert(5 == ex::apply(fp, t), "");
+ }
+ // functor
+ {
+ constexpr Tuple t{3, 4};
+ constexpr A_int_2 a;
+ static_assert(7 == ex::apply(a, t), "");
+ }
+}
+
+int main()
+{
+ test_0<std::tuple<>>();
+ test_1<std::tuple<int>>();
+ test_2<std::tuple<int, int>>();
+ test_2<std::pair<int, int>>();
+}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/extended_types.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/extended_types.pass.cpp
new file mode 100644
index 0000000..3225549
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/extended_types.pass.cpp
@@ -0,0 +1,423 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Testing extended function types. The extented function types are those
+// named by INVOKE but that are not actual callable objects. These include
+// bullets 1-4 of invoke.
+
+#include <experimental/tuple>
+#include <array>
+#include <utility>
+#include <cassert>
+
+int count = 0;
+
+struct A_int_0
+{
+ A_int_0() : obj1(0){}
+ A_int_0(int x) : obj1(x) {}
+ int mem1() { return ++count; }
+ int mem2() const { return ++count; }
+ int const obj1;
+};
+
+struct A_int_1
+{
+ A_int_1() {}
+ A_int_1(int) {}
+ int mem1(int x) { return count += x; }
+ int mem2(int x) const { return count += x; }
+};
+
+struct A_int_2
+{
+ A_int_2() {}
+ A_int_2(int) {}
+ int mem1(int x, int y) { return count += (x + y); }
+ int mem2(int x, int y) const { return count += (x + y); }
+};
+
+template <class A>
+struct A_wrap
+{
+ A_wrap() {}
+ A_wrap(int x) : m_a(x) {}
+ A & operator*() { return m_a; }
+ A const & operator*() const { return m_a; }
+ A m_a;
+};
+
+typedef A_wrap<A_int_0> A_wrap_0;
+typedef A_wrap<A_int_1> A_wrap_1;
+typedef A_wrap<A_int_2> A_wrap_2;
+
+
+template <class A>
+struct A_base : public A
+{
+ A_base() : A() {}
+ A_base(int x) : A(x) {}
+};
+
+typedef A_base<A_int_0> A_base_0;
+typedef A_base<A_int_1> A_base_1;
+typedef A_base<A_int_2> A_base_2;
+
+namespace ex = std::experimental;
+
+template <
+ class Tuple, class ConstTuple
+ , class TuplePtr, class ConstTuplePtr
+ , class TupleWrap, class ConstTupleWrap
+ , class TupleBase, class ConstTupleBase
+ >
+void test_ext_int_0()
+{
+ count = 0;
+ typedef A_int_0 T;
+ typedef A_wrap_0 Wrap;
+ typedef A_base_0 Base;
+
+ typedef int(T::*mem1_t)();
+ mem1_t mem1 = &T::mem1;
+
+ typedef int(T::*mem2_t)() const;
+ mem2_t mem2 = &T::mem2;
+
+ typedef int const T::*obj1_t;
+ obj1_t obj1 = &T::obj1;
+
+ // member function w/ref
+ {
+ T a;
+ Tuple t{a};
+ assert(1 == ex::apply(mem1, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // member function w/pointer
+ {
+ T a;
+ TuplePtr t{&a};
+ assert(1 == ex::apply(mem1, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // member function w/base
+ {
+ Base a;
+ TupleBase t{a};
+ assert(1 == ex::apply(mem1, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // member function w/wrap
+ {
+ Wrap a;
+ TupleWrap t{a};
+ assert(1 == ex::apply(mem1, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // const member function w/ref
+ {
+ T const a;
+ ConstTuple t{a};
+ assert(1 == ex::apply(mem2, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // const member function w/pointer
+ {
+ T const a;
+ ConstTuplePtr t{&a};
+ assert(1 == ex::apply(mem2, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // const member function w/base
+ {
+ Base const a;
+ ConstTupleBase t{a};
+ assert(1 == ex::apply(mem2, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // const member function w/wrapper
+ {
+ Wrap const a;
+ ConstTupleWrap t{a};
+ assert(1 == ex::apply(mem2, t));
+ assert(1 == count);
+ }
+ // member object w/ref
+ {
+ T a{42};
+ Tuple t{a};
+ assert(42 == ex::apply(obj1, t));
+ }
+ // member object w/pointer
+ {
+ T a{42};
+ TuplePtr t{&a};
+ assert(42 == ex::apply(obj1, t));
+ }
+ // member object w/base
+ {
+ Base a{42};
+ TupleBase t{a};
+ assert(42 == ex::apply(obj1, t));
+ }
+ // member object w/wrapper
+ {
+ Wrap a{42};
+ TupleWrap t{a};
+ assert(42 == ex::apply(obj1, t));
+ }
+}
+
+
+template <
+ class Tuple, class ConstTuple
+ , class TuplePtr, class ConstTuplePtr
+ , class TupleWrap, class ConstTupleWrap
+ , class TupleBase, class ConstTupleBase
+ >
+void test_ext_int_1()
+{
+ count = 0;
+ typedef A_int_1 T;
+ typedef A_wrap_1 Wrap;
+ typedef A_base_1 Base;
+
+ typedef int(T::*mem1_t)(int);
+ mem1_t mem1 = &T::mem1;
+
+ typedef int(T::*mem2_t)(int) const;
+ mem2_t mem2 = &T::mem2;
+
+ // member function w/ref
+ {
+ T a;
+ Tuple t{a, 2};
+ assert(2 == ex::apply(mem1, t));
+ assert(count == 2);
+ }
+ count = 0;
+ // member function w/pointer
+ {
+ T a;
+ TuplePtr t{&a, 3};
+ assert(3 == ex::apply(mem1, t));
+ assert(count == 3);
+ }
+ count = 0;
+ // member function w/base
+ {
+ Base a;
+ TupleBase t{a, 4};
+ assert(4 == ex::apply(mem1, t));
+ assert(count == 4);
+ }
+ count = 0;
+ // member function w/wrap
+ {
+ Wrap a;
+ TupleWrap t{a, 5};
+ assert(5 == ex::apply(mem1, t));
+ assert(count == 5);
+ }
+ count = 0;
+ // const member function w/ref
+ {
+ T const a;
+ ConstTuple t{a, 6};
+ assert(6 == ex::apply(mem2, t));
+ assert(count == 6);
+ }
+ count = 0;
+ // const member function w/pointer
+ {
+ T const a;
+ ConstTuplePtr t{&a, 7};
+ assert(7 == ex::apply(mem2, t));
+ assert(count == 7);
+ }
+ count = 0;
+ // const member function w/base
+ {
+ Base const a;
+ ConstTupleBase t{a, 8};
+ assert(8 == ex::apply(mem2, t));
+ assert(count == 8);
+ }
+ count = 0;
+ // const member function w/wrapper
+ {
+ Wrap const a;
+ ConstTupleWrap t{a, 9};
+ assert(9 == ex::apply(mem2, t));
+ assert(9 == count);
+ }
+}
+
+
+template <
+ class Tuple, class ConstTuple
+ , class TuplePtr, class ConstTuplePtr
+ , class TupleWrap, class ConstTupleWrap
+ , class TupleBase, class ConstTupleBase
+ >
+void test_ext_int_2()
+{
+ count = 0;
+ typedef A_int_2 T;
+ typedef A_wrap_2 Wrap;
+ typedef A_base_2 Base;
+
+ typedef int(T::*mem1_t)(int, int);
+ mem1_t mem1 = &T::mem1;
+
+ typedef int(T::*mem2_t)(int, int) const;
+ mem2_t mem2 = &T::mem2;
+
+ // member function w/ref
+ {
+ T a;
+ Tuple t{a, 1, 1};
+ assert(2 == ex::apply(mem1, t));
+ assert(count == 2);
+ }
+ count = 0;
+ // member function w/pointer
+ {
+ T a;
+ TuplePtr t{&a, 1, 2};
+ assert(3 == ex::apply(mem1, t));
+ assert(count == 3);
+ }
+ count = 0;
+ // member function w/base
+ {
+ Base a;
+ TupleBase t{a, 2, 2};
+ assert(4 == ex::apply(mem1, t));
+ assert(count == 4);
+ }
+ count = 0;
+ // member function w/wrap
+ {
+ Wrap a;
+ TupleWrap t{a, 2, 3};
+ assert(5 == ex::apply(mem1, t));
+ assert(count == 5);
+ }
+ count = 0;
+ // const member function w/ref
+ {
+ T const a;
+ ConstTuple t{a, 3, 3};
+ assert(6 == ex::apply(mem2, t));
+ assert(count == 6);
+ }
+ count = 0;
+ // const member function w/pointer
+ {
+ T const a;
+ ConstTuplePtr t{&a, 3, 4};
+ assert(7 == ex::apply(mem2, t));
+ assert(count == 7);
+ }
+ count = 0;
+ // const member function w/base
+ {
+ Base const a;
+ ConstTupleBase t{a, 4, 4};
+ assert(8 == ex::apply(mem2, t));
+ assert(count == 8);
+ }
+ count = 0;
+ // const member function w/wrapper
+ {
+ Wrap const a;
+ ConstTupleWrap t{a, 4, 5};
+ assert(9 == ex::apply(mem2, t));
+ assert(9 == count);
+ }
+}
+
+int main()
+{
+ {
+ test_ext_int_0<
+ std::tuple<A_int_0 &>, std::tuple<A_int_0 const &>
+ , std::tuple<A_int_0 *>, std::tuple<A_int_0 const *>
+ , std::tuple<A_wrap_0 &>, std::tuple<A_wrap_0 const &>
+ , std::tuple<A_base_0 &>, std::tuple<A_base_0 const &>
+ >();
+ test_ext_int_0<
+ std::tuple<A_int_0>, std::tuple<A_int_0 const>
+ , std::tuple<A_int_0 *>, std::tuple<A_int_0 const *>
+ , std::tuple<A_wrap_0>, std::tuple<A_wrap_0 const>
+ , std::tuple<A_base_0>, std::tuple<A_base_0 const>
+ >();
+ test_ext_int_0<
+ std::array<A_int_0, 1>, std::array<A_int_0 const, 1>
+ , std::array<A_int_0*, 1>, std::array<A_int_0 const*, 1>
+ , std::array<A_wrap_0, 1>, std::array<A_wrap_0 const, 1>
+ , std::array<A_base_0, 1>, std::array<A_base_0 const, 1>
+ >();
+ }
+ {
+ test_ext_int_1<
+ std::tuple<A_int_1 &, int>, std::tuple<A_int_1 const &, int>
+ , std::tuple<A_int_1 *, int>, std::tuple<A_int_1 const *, int>
+ , std::tuple<A_wrap_1 &, int>, std::tuple<A_wrap_1 const &, int>
+ , std::tuple<A_base_1 &, int>, std::tuple<A_base_1 const &, int>
+ >();
+ test_ext_int_1<
+ std::tuple<A_int_1, int>, std::tuple<A_int_1 const, int>
+ , std::tuple<A_int_1 *, int>, std::tuple<A_int_1 const *, int>
+ , std::tuple<A_wrap_1, int>, std::tuple<A_wrap_1 const, int>
+ , std::tuple<A_base_1, int>, std::tuple<A_base_1 const, int>
+ >();
+ test_ext_int_1<
+ std::pair<A_int_1 &, int>, std::pair<A_int_1 const &, int>
+ , std::pair<A_int_1 *, int>, std::pair<A_int_1 const *, int>
+ , std::pair<A_wrap_1 &, int>, std::pair<A_wrap_1 const &, int>
+ , std::pair<A_base_1 &, int>, std::pair<A_base_1 const &, int>
+ >();
+ test_ext_int_1<
+ std::pair<A_int_1, int>, std::pair<A_int_1 const, int>
+ , std::pair<A_int_1 *, int>, std::pair<A_int_1 const *, int>
+ , std::pair<A_wrap_1, int>, std::pair<A_wrap_1 const, int>
+ , std::pair<A_base_1, int>, std::pair<A_base_1 const, int>
+ >();
+ }
+ {
+ test_ext_int_2<
+ std::tuple<A_int_2 &, int, int>, std::tuple<A_int_2 const &, int, int>
+ , std::tuple<A_int_2 *, int, int>, std::tuple<A_int_2 const *, int, int>
+ , std::tuple<A_wrap_2 &, int, int>, std::tuple<A_wrap_2 const &, int, int>
+ , std::tuple<A_base_2 &, int, int>, std::tuple<A_base_2 const &, int, int>
+ >();
+ test_ext_int_2<
+ std::tuple<A_int_2, int, int>, std::tuple<A_int_2 const, int, int>
+ , std::tuple<A_int_2 *, int, int>, std::tuple<A_int_2 const *, int, int>
+ , std::tuple<A_wrap_2, int, int>, std::tuple<A_wrap_2 const, int, int>
+ , std::tuple<A_base_2, int, int>, std::tuple<A_base_2 const, int, int>
+ >();
+ }
+}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/large_arity.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/large_arity.pass.cpp
new file mode 100644
index 0000000..027258a
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/large_arity.pass.cpp
@@ -0,0 +1,146 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Stress testing large arities with tuple and array.
+
+#include <experimental/tuple>
+#include <array>
+#include <utility>
+#include <cassert>
+
+////////////////////////////////////////////////////////////////////////////////
+template <class T, std::size_t Dummy = 0>
+struct always_imp
+{
+ typedef T type;
+};
+
+template <class T, std::size_t Dummy = 0>
+using always_t = typename always_imp<T, Dummy>::type;
+
+////////////////////////////////////////////////////////////////////////////////
+template <class Tuple, class Idx>
+struct make_function;
+
+template <class Tp, std::size_t ...Idx>
+struct make_function<Tp, std::integer_sequence<std::size_t, Idx...>>
+{
+ using type = bool (*)(always_t<Tp, Idx>...);
+};
+
+template <class Tp, std::size_t Size>
+using make_function_t = typename make_function<Tp, std::make_index_sequence<Size>>::type;
+
+////////////////////////////////////////////////////////////////////////////////
+template <class Tp, class Idx>
+struct make_tuple_imp;
+
+////////////////////////////////////////////////////////////////////////////////
+template <class Tp, std::size_t ...Idx>
+struct make_tuple_imp<Tp, std::integer_sequence<std::size_t, Idx...>>
+{
+ using type = std::tuple<always_t<Tp, Idx>...>;
+};
+
+template <class Tp, std::size_t Size>
+using make_tuple_t = typename make_tuple_imp<Tp, std::make_index_sequence<Size>>::type;
+
+template <class ...Types>
+bool test_apply_fn(Types...) { return true; }
+
+namespace ex = std::experimental;
+
+template <std::size_t Size>
+void test_all()
+{
+
+ using A = std::array<int, Size>;
+ using ConstA = std::array<int const, Size>;
+
+ using Tuple = make_tuple_t<int, Size>;
+ using CTuple = make_tuple_t<const int, Size>;
+
+ using ValFn = make_function_t<int, Size>;
+ ValFn val_fn = &test_apply_fn;
+
+ using RefFn = make_function_t<int &, Size>;
+ RefFn ref_fn = &test_apply_fn;
+
+ using CRefFn = make_function_t<int const &, Size>;
+ CRefFn cref_fn = &test_apply_fn;
+
+ using RRefFn = make_function_t<int &&, Size>;
+ RRefFn rref_fn = &test_apply_fn;
+
+ {
+ A a{};
+ assert(ex::apply(val_fn, a));
+ assert(ex::apply(ref_fn, a));
+ assert(ex::apply(cref_fn, a));
+ assert(ex::apply(rref_fn, std::move(a)));
+ }
+ {
+ ConstA a{};
+ assert(ex::apply(val_fn, a));
+ assert(ex::apply(cref_fn, a));
+ }
+ {
+ Tuple a{};
+ assert(ex::apply(val_fn, a));
+ assert(ex::apply(ref_fn, a));
+ assert(ex::apply(cref_fn, a));
+ assert(ex::apply(rref_fn, std::move(a)));
+ }
+ {
+ CTuple a{};
+ assert(ex::apply(val_fn, a));
+ assert(ex::apply(cref_fn, a));
+ }
+
+}
+
+
+template <std::size_t Size>
+void test_one()
+{
+ using A = std::array<int, Size>;
+ using Tuple = make_tuple_t<int, Size>;
+
+ using ValFn = make_function_t<int, Size>;
+ ValFn val_fn = &test_apply_fn;
+
+ {
+ A a{};
+ assert(ex::apply(val_fn, a));
+ }
+ {
+ Tuple a{};
+ assert(ex::apply(val_fn, a));
+ }
+}
+
+int main()
+{
+ // Instantiate with 1-5 arguments.
+ test_all<1>();
+ test_all<2>();
+ test_all<3>();
+ test_all<4>();
+ test_all<5>();
+
+ // Stress test with 128.
+ test_one<128>();
+ //test_one<256>();
+}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/ref_qualifiers.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/ref_qualifiers.pass.cpp
new file mode 100644
index 0000000..3cf259f
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/ref_qualifiers.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Testing ref qualified functions
+
+#include <experimental/tuple>
+#include <cassert>
+
+struct func_obj
+{
+ constexpr func_obj() {}
+
+ constexpr int operator()() const & { return 1; }
+ constexpr int operator()() const && { return 2; }
+ constexpr int operator()() & { return 3; }
+ constexpr int operator()() && { return 4; }
+};
+
+namespace ex = std::experimental;
+
+int main()
+{
+// TODO(ericwf): Re-enable constexpr support
+/*
+ {
+ constexpr func_obj f;
+ constexpr std::tuple<> tp;
+
+ static_assert(1 == ex::apply(static_cast<func_obj const &>(f), tp), "");
+ static_assert(2 == ex::apply(static_cast<func_obj const &&>(f), tp), "");
+ }
+*/
+ {
+ func_obj f;
+ std::tuple<> tp;
+ assert(1 == ex::apply(static_cast<func_obj const &>(f), tp));
+ assert(2 == ex::apply(static_cast<func_obj const &&>(f), tp));
+ assert(3 == ex::apply(static_cast<func_obj &>(f), tp));
+ assert(4 == ex::apply(static_cast<func_obj &&>(f), tp));
+ }
+}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp
new file mode 100644
index 0000000..1ec38da
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/return_type.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Test the return type deduction.
+
+#include <experimental/tuple>
+#include <cassert>
+
+static int my_int = 42;
+
+template <int N> struct index {};
+
+void f(index<0>) {}
+
+int f(index<1>) { return 0; }
+int const f(index<2>) { return 0; }
+int volatile f(index<3>) { return 0; }
+int const volatile f(index<4>) { return 0; }
+
+int & f(index<5>) { return static_cast<int &>(my_int); }
+int const & f(index<6>) { return static_cast<int const &>(my_int); }
+int volatile & f(index<7>) { return static_cast<int volatile &>(my_int); }
+int const volatile & f(index<8>) { return static_cast<int const volatile &>(my_int); }
+
+int && f(index<9>) { return static_cast<int &&>(my_int); }
+int const && f(index<10>) { return static_cast<int const &&>(my_int); }
+int volatile && f(index<11>) { return static_cast<int volatile &&>(my_int); }
+int const volatile && f(index<12>) { return static_cast<int const volatile &&>(my_int); }
+
+int * f(index<13>) { return static_cast<int *>(&my_int); }
+int const * f(index<14>) { return static_cast<int const *>(&my_int); }
+int volatile * f(index<15>) { return static_cast<int volatile *>(&my_int); }
+int const volatile * f(index<16>) { return static_cast<int const volatile *>(&my_int); }
+
+
+template <int Func, class Expect>
+void test()
+{
+ using F = decltype((f(index<Func>{})));
+ static_assert(std::is_same<F, Expect>::value, "");
+}
+
+namespace ex = std::experimental;
+
+int main()
+{
+ test<0, void>();
+ test<1, int>();
+ //test<2, int const>();
+ //test<3, int volatile>();
+ //test<4, int const volatile>();
+ test<5, int &>();
+ test<6, int const &>();
+ test<7, int volatile &>();
+ test<8, int const volatile &>();
+ test<9, int &&>();
+ test<10, int const &&>();
+ test<11, int volatile &&>();
+ test<12, int const volatile &&>();
+ test<13, int *>();
+ test<14, int const *>();
+ test<15, int volatile *>();
+ test<16, int const volatile *>();
+}
diff --git a/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp b/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp
new file mode 100644
index 0000000..5d3d564
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple.apply/types.pass.cpp
@@ -0,0 +1,427 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class F, class T> constexpr decltype(auto) apply(F &&, T &&)
+
+// Test function types.
+
+#include <experimental/tuple>
+#include <array>
+#include <utility>
+#include <cassert>
+
+namespace ex = std::experimental;
+
+int count = 0;
+
+void f_void_0() { ++count; }
+void f_void_1(int i) { count += i; }
+void f_void_2(int x, int y) { count += (x + y); }
+void f_void_3(int x, int y, int z) { count += (x + y + z); }
+
+int f_int_0() { return ++count; }
+int f_int_1(int x) { return count += x; }
+int f_int_2(int x, int y) { return count += (x + y); }
+int f_int_3(int x, int y, int z) { return count += (x + y + z); }
+
+struct A_void_0
+{
+ A_void_0() {}
+ void operator()() { ++count; }
+ void operator()() const { ++count; ++count; }
+};
+
+struct A_void_1
+{
+ A_void_1() {}
+ void operator()(int x) { count += x; }
+ void operator()(int x) const { count += x + 1; }
+};
+
+struct A_void_2
+{
+ A_void_2() {}
+ void operator()(int x, int y) { count += (x + y); }
+ void operator()(int x, int y) const { count += (x + y) + 1; }
+};
+
+struct A_void_3
+{
+ A_void_3() {}
+ void operator()(int x, int y, int z) { count += (x + y + z); }
+ void operator()(int x, int y, int z) const { count += (x + y + z) + 1; }
+};
+
+
+struct A_int_0
+{
+ A_int_0() {}
+ int operator()() { return ++count; }
+ int operator()() const { ++count; return ++count; }
+};
+
+struct A_int_1
+{
+ A_int_1() {}
+ int operator()(int x) { return count += x; }
+ int operator()(int x) const { return count += (x + 1); }
+
+};
+
+struct A_int_2
+{
+ A_int_2() {}
+ int operator()(int x, int y) { return count += (x + y); }
+ int operator()(int x, int y) const { return count += (x + y + 1); }
+};
+
+struct A_int_3
+{
+ A_int_3() {}
+ int operator()(int x, int y, int z) { return count += (x + y + z); }
+ int operator()(int x, int y, int z) const { return count += (x + y + z + 1); }
+};
+
+
+template <class Tuple>
+void test_void_0()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{};
+ ex::apply(f_void_0, t);
+ assert(count == 1);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{};
+ auto fp = &f_void_0;
+ ex::apply(fp, t);
+ assert(count == 1);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{};
+ A_void_0 a;
+ ex::apply(a, t);
+ assert(count == 1);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{};
+ A_void_0 const a;
+ ex::apply(a, t);
+ assert(count == 2);
+ }
+}
+
+template <class Tuple>
+void test_void_1()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{1};
+ ex::apply(f_void_1, t);
+ assert(count == 1);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{2};
+ void (*fp)(int) = f_void_1;
+ ex::apply(fp, t);
+ assert(count == 2);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{3};
+ A_void_1 fn;
+ ex::apply(fn, t);
+ assert(count == 3);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{4};
+ A_void_1 const a;
+ ex::apply(a, t);
+ assert(count == 5);
+ }
+}
+
+template <class Tuple>
+void test_void_2()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{1, 2};
+ ex::apply(f_void_2, t);
+ assert(count == 3);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{2, 3};
+ auto fp = &f_void_2;
+ ex::apply(fp, t);
+ assert(count == 5);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{3, 4};
+ A_void_2 a;
+ ex::apply(a, t);
+ assert(count == 7);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{4, 5};
+ A_void_2 const a;
+ ex::apply(a, t);
+ assert(count == 10);
+ }
+}
+
+template <class Tuple>
+void test_void_3()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{1, 2, 3};
+ ex::apply(f_void_3, t);
+ assert(count == 6);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{2, 3, 4};
+ auto fp = &f_void_3;
+ ex::apply(fp, t);
+ assert(count == 9);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{3, 4, 5};
+ A_void_3 a;
+ ex::apply(a, t);
+ assert(count == 12);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{4, 5, 6};
+ A_void_3 const a;
+ ex::apply(a, t);
+ assert(count == 16);
+ }
+}
+
+
+
+template <class Tuple>
+void test_int_0()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{};
+ assert(1 == ex::apply(f_int_0, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{};
+ auto fp = &f_int_0;
+ assert(1 == ex::apply(fp, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{};
+ A_int_0 a;
+ assert(1 == ex::apply(a, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{};
+ A_int_0 const a;
+ assert(2 == ex::apply(a, t));
+ assert(count == 2);
+ }
+}
+
+template <class Tuple>
+void test_int_1()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{1};
+ assert(1 == ex::apply(f_int_1, t));
+ assert(count == 1);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{2};
+ int (*fp)(int) = f_int_1;
+ assert(2 == ex::apply(fp, t));
+ assert(count == 2);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{3};
+ A_int_1 fn;
+ assert(3 == ex::apply(fn, t));
+ assert(count == 3);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{4};
+ A_int_1 const a;
+ assert(5 == ex::apply(a, t));
+ assert(count == 5);
+ }
+}
+
+template <class Tuple>
+void test_int_2()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{1, 2};
+ assert(3 == ex::apply(f_int_2, t));
+ assert(count == 3);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{2, 3};
+ auto fp = &f_int_2;
+ assert(5 == ex::apply(fp, t));
+ assert(count == 5);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{3, 4};
+ A_int_2 a;
+ assert(7 == ex::apply(a, t));
+ assert(count == 7);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{4, 5};
+ A_int_2 const a;
+ assert(10 == ex::apply(a, t));
+ assert(count == 10);
+ }
+}
+
+template <class Tuple>
+void test_int_3()
+{
+ count = 0;
+ // function
+ {
+ Tuple t{1, 2, 3};
+ assert(6 == ex::apply(f_int_3, t));
+ assert(count == 6);
+ }
+ count = 0;
+ // function pointer
+ {
+ Tuple t{2, 3, 4};
+ auto fp = &f_int_3;
+ assert(9 == ex::apply(fp, t));
+ assert(count == 9);
+ }
+ count = 0;
+ // functor
+ {
+ Tuple t{3, 4, 5};
+ A_int_3 a;
+ assert(12 == ex::apply(a, t));
+ assert(count == 12);
+ }
+ count = 0;
+ // const functor
+ {
+ Tuple t{4, 5, 6};
+ A_int_3 const a;
+ assert(16 == ex::apply(a, t));
+ assert(count == 16);
+ }
+}
+
+template <class Tuple>
+void test_0()
+{
+ test_void_0<Tuple>();
+ test_int_0<Tuple>();
+}
+
+template <class Tuple>
+void test_1()
+{
+ test_void_1<Tuple>();
+ test_int_1<Tuple>();
+}
+
+template <class Tuple>
+void test_2()
+{
+ test_void_2<Tuple>();
+ test_int_2<Tuple>();
+}
+
+template <class Tuple>
+void test_3()
+{
+ test_void_3<Tuple>();
+ test_int_3<Tuple>();
+}
+
+int main()
+{
+ test_0<std::tuple<>>();
+
+ test_1<std::tuple<int>>();
+ test_1<std::array<int, 1>>();
+
+ test_2<std::tuple<int, int>>();
+ test_2<std::pair<int, int>>();
+ test_2<std::array<int, 2>>();
+
+ test_3<std::tuple<int, int, int>>();
+ test_3<std::array<int, 3>>();
+}
diff --git a/test/std/experimental/utilities/tuple/tuple_size_v.fail.cpp b/test/std/experimental/utilities/tuple/tuple_size_v.fail.cpp
new file mode 100644
index 0000000..a25b18c
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple_size_v.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;
+
+// Test with reference
+
+#include <experimental/tuple>
+
+namespace ex = std::experimental;
+
+int main()
+{
+ auto x = ex::tuple_size_v<std::tuple<> &>;
+}
diff --git a/test/std/experimental/utilities/tuple/tuple_size_v.pass.cpp b/test/std/experimental/utilities/tuple/tuple_size_v.pass.cpp
new file mode 100644
index 0000000..d7a5aa6
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple_size_v.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;
+
+#include <experimental/tuple>
+#include <utility>
+#include <array>
+
+namespace ex = std::experimental;
+
+template <class Tuple, int Expect>
+void test()
+{
+ static_assert(ex::tuple_size_v<Tuple> == Expect, "");
+ static_assert(ex::tuple_size_v<Tuple> == std::tuple_size<Tuple>::value, "");
+ static_assert(ex::tuple_size_v<Tuple const> == std::tuple_size<Tuple>::value, "");
+ static_assert(ex::tuple_size_v<Tuple volatile> == std::tuple_size<Tuple>::value, "");
+ static_assert(ex::tuple_size_v<Tuple const volatile> == std::tuple_size<Tuple>::value, "");
+}
+
+int main()
+{
+ test<std::tuple<>, 0>();
+
+ test<std::tuple<int>, 1>();
+ test<std::array<int, 1>, 1>();
+
+ test<std::tuple<int, int>, 2>();
+ test<std::pair<int, int>, 2>();
+ test<std::array<int, 2>, 2>();
+
+ test<std::tuple<int, int, int>, 3>();
+ test<std::array<int, 3>, 3>();
+}
diff --git a/test/std/experimental/utilities/tuple/tuple_size_v_2.fail.cpp b/test/std/experimental/utilities/tuple/tuple_size_v_2.fail.cpp
new file mode 100644
index 0000000..a95ac49
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple_size_v_2.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;
+
+// Test with non tuple type
+
+#include <experimental/tuple>
+
+namespace ex = std::experimental;
+
+int main()
+{
+ auto x = ex::tuple_size_v<int>;
+}
diff --git a/test/std/experimental/utilities/tuple/tuple_size_v_3.fail.cpp b/test/std/experimental/utilities/tuple/tuple_size_v_3.fail.cpp
new file mode 100644
index 0000000..7c2f0cc
--- /dev/null
+++ b/test/std/experimental/utilities/tuple/tuple_size_v_3.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+// <experimental/tuple>
+
+// template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value;
+
+// Test with pointer
+
+#include <experimental/tuple>
+
+namespace ex = std::experimental;
+
+int main()
+{
+ auto x = ex::tuple_size_v<std::tuple<>*>;
+}
diff --git a/test/std/input.output/file.streams/c.files/cstdio.pass.cpp b/test/std/input.output/file.streams/c.files/cstdio.pass.cpp
index 1a60dd6..ec4ad8a 100644
--- a/test/std/input.output/file.streams/c.files/cstdio.pass.cpp
+++ b/test/std/input.output/file.streams/c.files/cstdio.pass.cpp
@@ -88,27 +88,17 @@
std::size_t s = 0;
char* cp = 0;
std::va_list va;
- static_assert((std::is_same<decltype(std::remove("")), int>::value), "");
- static_assert((std::is_same<decltype(std::rename("","")), int>::value), "");
- static_assert((std::is_same<decltype(std::tmpfile()), std::FILE*>::value), "");
- static_assert((std::is_same<decltype(std::tmpnam(cp)), char*>::value), "");
static_assert((std::is_same<decltype(std::fclose(fp)), int>::value), "");
static_assert((std::is_same<decltype(std::fflush(fp)), int>::value), "");
- static_assert((std::is_same<decltype(std::fopen("", "")), std::FILE*>::value), "");
- static_assert((std::is_same<decltype(std::freopen("", "", fp)), std::FILE*>::value), "");
static_assert((std::is_same<decltype(std::setbuf(fp,cp)), void>::value), "");
static_assert((std::is_same<decltype(std::vfprintf(fp,"",va)), int>::value), "");
static_assert((std::is_same<decltype(std::fprintf(fp," ")), int>::value), "");
static_assert((std::is_same<decltype(std::fscanf(fp,"")), int>::value), "");
- static_assert((std::is_same<decltype(std::printf(" ")), int>::value), "");
- static_assert((std::is_same<decltype(std::scanf(" ")), int>::value), "");
static_assert((std::is_same<decltype(std::snprintf(cp,0," ")), int>::value), "");
static_assert((std::is_same<decltype(std::sprintf(cp," ")), int>::value), "");
static_assert((std::is_same<decltype(std::sscanf("","")), int>::value), "");
static_assert((std::is_same<decltype(std::vfprintf(fp,"",va)), int>::value), "");
static_assert((std::is_same<decltype(std::vfscanf(fp,"",va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vprintf(" ",va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vscanf("",va)), int>::value), "");
static_assert((std::is_same<decltype(std::vsnprintf(cp,0," ",va)), int>::value), "");
static_assert((std::is_same<decltype(std::vsprintf(cp," ",va)), int>::value), "");
static_assert((std::is_same<decltype(std::vsscanf("","",va)), int>::value), "");
@@ -117,13 +107,7 @@
static_assert((std::is_same<decltype(std::fputc(0,fp)), int>::value), "");
static_assert((std::is_same<decltype(std::fputs("",fp)), int>::value), "");
static_assert((std::is_same<decltype(std::getc(fp)), int>::value), "");
- static_assert((std::is_same<decltype(std::getchar()), int>::value), "");
-#if _LIBCPP_STD_VER <= 11
- static_assert((std::is_same<decltype(std::gets(cp)), char*>::value), "");
-#endif
static_assert((std::is_same<decltype(std::putc(0,fp)), int>::value), "");
- static_assert((std::is_same<decltype(std::putchar(0)), int>::value), "");
- static_assert((std::is_same<decltype(std::puts("")), int>::value), "");
static_assert((std::is_same<decltype(std::ungetc(0,fp)), int>::value), "");
static_assert((std::is_same<decltype(std::fread((void*)0,0,0,fp)), std::size_t>::value), "");
static_assert((std::is_same<decltype(std::fwrite((const void*)0,0,0,fp)), std::size_t>::value), "");
@@ -136,4 +120,29 @@
static_assert((std::is_same<decltype(std::feof(fp)), int>::value), "");
static_assert((std::is_same<decltype(std::ferror(fp)), int>::value), "");
static_assert((std::is_same<decltype(std::perror("")), void>::value), "");
+
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
+ static_assert((std::is_same<decltype(std::fopen("", "")), std::FILE*>::value), "");
+ static_assert((std::is_same<decltype(std::freopen("", "", fp)), std::FILE*>::value), "");
+ static_assert((std::is_same<decltype(std::remove("")), int>::value), "");
+ static_assert((std::is_same<decltype(std::rename("","")), int>::value), "");
+ static_assert((std::is_same<decltype(std::tmpfile()), std::FILE*>::value), "");
+ static_assert((std::is_same<decltype(std::tmpnam(cp)), char*>::value), "");
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDIN
+ static_assert((std::is_same<decltype(std::getchar()), int>::value), "");
+#if _LIBCPP_STD_VER <= 11
+ static_assert((std::is_same<decltype(std::gets(cp)), char*>::value), "");
+#endif
+ static_assert((std::is_same<decltype(std::scanf(" ")), int>::value), "");
+ static_assert((std::is_same<decltype(std::vscanf("",va)), int>::value), "");
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+ static_assert((std::is_same<decltype(std::printf(" ")), int>::value), "");
+ static_assert((std::is_same<decltype(std::putchar(0)), int>::value), "");
+ static_assert((std::is_same<decltype(std::puts("")), int>::value), "");
+ static_assert((std::is_same<decltype(std::vprintf(" ",va)), int>::value), "");
+#endif
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/fopen.fail.cpp
similarity index 71%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/fopen.fail.cpp
index b58f5c5..4d83296 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/fopen.fail.cpp
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
+#include <cstdio>
+
+int main() {
+ // fopen is not available on systems without a global filesystem namespace.
+ std::fopen("", "");
}
diff --git a/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/lit.local.cfg b/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/lit.local.cfg
new file mode 100644
index 0000000..4ea6709
--- /dev/null
+++ b/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/lit.local.cfg
@@ -0,0 +1,2 @@
+if 'libcpp-has-no-global-filesystem-namespace' not in config.available_features:
+ config.unsupported = True
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/rename.fail.cpp
similarity index 71%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/rename.fail.cpp
index b58f5c5..deca9bf 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/input.output/file.streams/c.files/no.global.filesystem.namespace/rename.fail.cpp
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
+#include <cstdio>
+
+int main() {
+ // rename is not available on systems without a global filesystem namespace.
+ std::rename("", "");
}
diff --git a/test/std/input.output/file.streams/fstreams/lit.local.cfg b/test/std/input.output/file.streams/fstreams/lit.local.cfg
new file mode 100644
index 0000000..25ac02b
--- /dev/null
+++ b/test/std/input.output/file.streams/fstreams/lit.local.cfg
@@ -0,0 +1,2 @@
+if 'libcpp-has-no-global-filesystem-namespace' in config.available_features:
+ config.unsupported = True
diff --git a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp
index 114bba9..b74d99a 100644
--- a/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp
+++ b/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp
@@ -59,18 +59,27 @@
assert(os.fail());
}
{
- testbuf<char> sb;
- std::ostream os(&sb);
- const void* n = 0;
- os << n;
- assert(os.good());
- // %p is implementation defined.
- // On some platforms (Windows), it's a hex number without
- // any leading 0x like prefix.
- // In that format, we assume a null pointer will yield 2 '0' hex digits
- // for each 8 bits of address space.
- assert(sb.str() == "0x0" || sb.str() == "(nil)" ||
- sb.str() == std::string(sizeof(void*)*2,'0'));
+ testbuf<char> sb1;
+ std::ostream os1(&sb1);
+ int n1;
+ os1 << &n1;
+ assert(os1.good());
+ std::string s1(sb1.str());
+
+ testbuf<char> sb2;
+ std::ostream os2(&sb2);
+ int n2;
+ os2 << &n2;
+ assert(os2.good());
+ std::string s2(sb2.str());
+
+ // %p is implementation defined. Instead of validating the
+ // output, at least ensure that it does not generate an empty
+ // string. Also make sure that given two distinct addresses, the
+ // output of %p is different.
+ assert(!s1.empty());
+ assert(!s2.empty());
+ assert(s1 != s2);
}
{
testbuf<char> sb;
diff --git a/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp.pass.cpp b/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp.pass.cpp
index e09627b..ec3fe48 100644
--- a/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp.pass.cpp
+++ b/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp.pass.cpp
@@ -40,11 +40,13 @@
int main()
{
{
+ seekpos_called = 0;
std::ostream os((std::streambuf*)0);
assert(&os.seekp(5) == &os);
assert(seekpos_called == 0);
}
{
+ seekpos_called = 0;
testbuf<char> sb;
std::ostream os(&sb);
assert(&os.seekp(10) == &os);
@@ -54,4 +56,13 @@
assert(seekpos_called == 2);
assert(os.fail());
}
+ { // See https://llvm.org/bugs/show_bug.cgi?id=21361
+ seekpos_called = 0;
+ testbuf<char> sb;
+ std::ostream os(&sb);
+ os.setstate(std::ios_base::eofbit);
+ assert(&os.seekp(10) == &os);
+ assert(seekpos_called == 1);
+ assert(os.rdstate() == std::ios_base::eofbit);
+ }
}
diff --git a/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp2.pass.cpp b/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp2.pass.cpp
index 69b26f3..ebfd24a 100644
--- a/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp2.pass.cpp
+++ b/test/std/input.output/iostream.format/output.streams/ostream.seeks/seekp2.pass.cpp
@@ -42,11 +42,13 @@
int main()
{
{
+ seekoff_called = 0;
std::ostream os((std::streambuf*)0);
assert(&os.seekp(5, std::ios_base::beg) == &os);
assert(seekoff_called == 0);
}
{
+ seekoff_called = 0;
testbuf<char> sb;
std::ostream os(&sb);
assert(&os.seekp(10, std::ios_base::beg) == &os);
@@ -56,4 +58,13 @@
assert(seekoff_called == 2);
assert(os.fail());
}
+ { // See https://llvm.org/bugs/show_bug.cgi?id=21361
+ seekoff_called = 0;
+ testbuf<char> sb;
+ std::ostream os(&sb);
+ os.setstate(std::ios_base::eofbit);
+ assert(&os.seekp(10, std::ios_base::beg) == &os);
+ assert(seekoff_called == 1);
+ assert(os.rdstate() == std::ios_base::eofbit);
+ }
}
diff --git a/test/std/input.output/iostream.objects/narrow.stream.objects/cerr.pass.cpp b/test/std/input.output/iostream.objects/narrow.stream.objects/cerr.pass.cpp
index 9206d17..cdf53f8 100644
--- a/test/std/input.output/iostream.objects/narrow.stream.objects/cerr.pass.cpp
+++ b/test/std/input.output/iostream.objects/narrow.stream.objects/cerr.pass.cpp
@@ -19,7 +19,11 @@
#if 0
std::cerr << "Hello World!\n";
#else
+#ifdef _LIBCPP_HAS_NO_STDOUT
+ assert(std::cerr.tie() == NULL);
+#else
assert(std::cerr.tie() == &std::cout);
+#endif
assert(std::cerr.flags() & std::ios_base::unitbuf);
#endif // 0
}
diff --git a/test/std/input.output/iostream.objects/narrow.stream.objects/cin.pass.cpp b/test/std/input.output/iostream.objects/narrow.stream.objects/cin.pass.cpp
index 3481598..1ce04ff 100644
--- a/test/std/input.output/iostream.objects/narrow.stream.objects/cin.pass.cpp
+++ b/test/std/input.output/iostream.objects/narrow.stream.objects/cin.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-has-no-stdin
+
// <iostream>
// istream cin;
@@ -23,6 +25,10 @@
std::cin >> i;
std::cout << "The number is : " << i << '\n';
#else // 0
+#ifdef _LIBCPP_HAS_NO_STDOUT
+ assert(std::cin.tie() == NULL);
+#else
assert(std::cin.tie() == &std::cout);
#endif
+#endif
}
diff --git a/test/std/input.output/iostream.objects/narrow.stream.objects/cout.pass.cpp b/test/std/input.output/iostream.objects/narrow.stream.objects/cout.pass.cpp
index 6000ae2..e5887e1 100644
--- a/test/std/input.output/iostream.objects/narrow.stream.objects/cout.pass.cpp
+++ b/test/std/input.output/iostream.objects/narrow.stream.objects/cout.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-has-no-stdout
+
// <iostream>
// istream cout;
diff --git a/test/std/input.output/iostream.objects/wide.stream.objects/wcerr.pass.cpp b/test/std/input.output/iostream.objects/wide.stream.objects/wcerr.pass.cpp
index 19a1dcd..b050781 100644
--- a/test/std/input.output/iostream.objects/wide.stream.objects/wcerr.pass.cpp
+++ b/test/std/input.output/iostream.objects/wide.stream.objects/wcerr.pass.cpp
@@ -19,7 +19,11 @@
#if 0
std::wcerr << L"Hello World!\n";
#else
+#ifdef _LIBCPP_HAS_NO_STDOUT
+ assert(std::wcerr.tie() == NULL);
+#else
assert(std::wcerr.tie() == &std::wcout);
+#endif
assert(std::wcerr.flags() & std::ios_base::unitbuf);
#endif // 0
}
diff --git a/test/std/input.output/iostream.objects/wide.stream.objects/wcin.pass.cpp b/test/std/input.output/iostream.objects/wide.stream.objects/wcin.pass.cpp
index 90a5668..6abd6af 100644
--- a/test/std/input.output/iostream.objects/wide.stream.objects/wcin.pass.cpp
+++ b/test/std/input.output/iostream.objects/wide.stream.objects/wcin.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-has-no-stdin
+
// <iostream>
// istream wcin;
@@ -23,6 +25,10 @@
std::wcin >> i;
std::wcout << L"The number is : " << i << L'\n';
#else // 0
+#ifdef _LIBCPP_HAS_NO_STDOUT
+ assert(std::wcin.tie() == NULL);
+#else
assert(std::wcin.tie() == &std::wcout);
#endif
+#endif
}
diff --git a/test/std/input.output/iostream.objects/wide.stream.objects/wcout.pass.cpp b/test/std/input.output/iostream.objects/wide.stream.objects/wcout.pass.cpp
index 7a546aa..6543e0a 100644
--- a/test/std/input.output/iostream.objects/wide.stream.objects/wcout.pass.cpp
+++ b/test/std/input.output/iostream.objects/wide.stream.objects/wcout.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: libcpp-has-no-stdout
+
// <iostream>
// istream wcout;
diff --git a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.locales/locales.pass.cpp b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.locales/locales.pass.cpp
index deb2dc7..95dd2db 100644
--- a/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.locales/locales.pass.cpp
+++ b/test/std/input.output/stream.buffers/streambuf/streambuf.members/streambuf.locales/locales.pass.cpp
@@ -45,7 +45,8 @@
{
test<char> t;
assert(t.getloc().name() == LOCALE_en_US_UTF_8);
- assert(t.pubimbue(std::locale(LOCALE_fr_FR_UTF_8)).name() == "en_US.UTF-8");
+ assert(t.pubimbue(std::locale(LOCALE_fr_FR_UTF_8)).name() ==
+ LOCALE_en_US_UTF_8);
assert(t.getloc().name() == LOCALE_fr_FR_UTF_8);
}
}
diff --git a/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/overflow.pass.cpp b/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/overflow.pass.cpp
index 3abf942..67363b5 100644
--- a/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/overflow.pass.cpp
+++ b/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/overflow.pass.cpp
@@ -29,7 +29,7 @@
: base(str, which) {}
typename base::int_type
- overflow(typename base::int_type c = base::type_traits::eof())
+ overflow(typename base::int_type c = base::traits_type::eof())
{++overflow_called; return base::overflow(c);}
void pbump(int n) {base::pbump(n);}
@@ -37,6 +37,10 @@
int main()
{
+ { // sanity check
+ testbuf<char> tb("");;
+ tb.overflow();
+ }
{
testbuf<char> sb("abc");
assert(sb.sputc('1') == '1');
diff --git a/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/pbackfail.pass.cpp b/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/pbackfail.pass.cpp
index 4af0e63..a050900 100644
--- a/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/pbackfail.pass.cpp
+++ b/test/std/input.output/string.streams/stringbuf/stringbuf.virtuals/pbackfail.pass.cpp
@@ -27,7 +27,7 @@
: base(str, which) {}
typename base::int_type
- pbackfail(typename base::int_type c = base::type_traits::eof())
+ pbackfail(typename base::int_type c = base::traits_type::eof())
{return base::pbackfail(c);}
void pbump(int n) {base::pbump(n);}
@@ -35,6 +35,10 @@
int main()
{
+ { // sanity check
+ testbuf<char> tb("");;
+ tb.pbackfail();
+ }
{
testbuf<char> sb("123", std::ios_base::in);
assert(sb.sgetc() == '1');
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp
similarity index 60%
rename from test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp
rename to test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp
index 7099c45..5e6cc54 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp
+++ b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.fail.cpp
@@ -7,18 +7,24 @@
//
//===----------------------------------------------------------------------===//
-// <functional>
+// <iterator>
-// class function<R()>
+// class istream_iterator
-// template<class F> function(F);
+// constexpr istream_iterator();
-#define _LIBCPP_HAS_NO_VARIADICS
-#include <functional>
+#include <iterator>
#include <cassert>
+struct S { S(); }; // not constexpr
+
int main()
{
- std::function<void()> f(static_cast<void(*)()>(0));
- assert(!f);
+#if __cplusplus >= 201103L
+ {
+ constexpr std::istream_iterator<S> it;
+ }
+#else
+#error "C++11 only test"
+#endif
}
diff --git a/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
index f6c3dba..bea07ec 100644
--- a/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
+++ b/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
@@ -11,13 +11,20 @@
// class istream_iterator
-// istream_iterator();
+// constexpr istream_iterator();
#include <iterator>
#include <cassert>
int main()
{
- std::istream_iterator<int> i;
- assert(i == std::istream_iterator<int>());
+ {
+ typedef std::istream_iterator<int> T;
+ T it;
+ assert(it == T());
+#if __cplusplus >= 201103L
+ constexpr T it2;
+#endif
+ }
+
}
diff --git a/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp b/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
index be55c97..85a70a0 100644
--- a/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
+++ b/test/std/iterators/stream.iterators/istream.iterator/types.pass.cpp
@@ -19,9 +19,14 @@
// typedef traits traits_type;
// typedef basic_istream<charT,traits> istream_type;
// ...
+//
+// If T is a literal type, then the default constructor shall be a constexpr constructor.
+// If T is a literal type, then this constructor shall be a trivial copy constructor.
+// If T is a literal type, then this destructor shall be a trivial destructor.
#include <iterator>
#include <type_traits>
+#include <string>
int main()
{
@@ -32,6 +37,9 @@
static_assert((std::is_same<I1::char_type, char>::value), "");
static_assert((std::is_same<I1::traits_type, std::char_traits<char> >::value), "");
static_assert((std::is_same<I1::istream_type, std::istream>::value), "");
+ static_assert( std::is_trivially_copy_constructible<I1>::value, "");
+ static_assert( std::is_trivially_destructible<I1>::value, "");
+
typedef std::istream_iterator<unsigned, wchar_t> I2;
static_assert((std::is_convertible<I2,
std::iterator<std::input_iterator_tag, unsigned, std::ptrdiff_t,
@@ -39,4 +47,10 @@
static_assert((std::is_same<I2::char_type, wchar_t>::value), "");
static_assert((std::is_same<I2::traits_type, std::char_traits<wchar_t> >::value), "");
static_assert((std::is_same<I2::istream_type, std::wistream>::value), "");
+ static_assert( std::is_trivially_copy_constructible<I2>::value, "");
+ static_assert( std::is_trivially_destructible<I2>::value, "");
+
+ typedef std::istream_iterator<std::string> I3;
+ static_assert(!std::is_trivially_copy_constructible<I3>::value, "");
+ static_assert(!std::is_trivially_destructible<I3>::value, "");
}
diff --git a/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp b/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
index d1eabba..46ac390 100644
--- a/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
+++ b/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
@@ -10,8 +10,11 @@
// <iterator>
// istreambuf_iterator
-
+//
// istreambuf_iterator() throw();
+//
+// All specializations of istreambuf_iterator shall have a trivial copy constructor,
+// a constexpr default constructor and a trivial destructor.
#include <iterator>
#include <sstream>
@@ -20,11 +23,19 @@
int main()
{
{
- std::istreambuf_iterator<char> i;
- assert(i == std::istreambuf_iterator<char>());
+ typedef std::istreambuf_iterator<char> T;
+ T it;
+ assert(it == T());
+#if __cplusplus >= 201103L
+ constexpr T it2;
+#endif
}
{
- std::istreambuf_iterator<wchar_t> i;
- assert(i == std::istreambuf_iterator<wchar_t>());
+ typedef std::istreambuf_iterator<wchar_t> T;
+ T it;
+ assert(it == T());
+#if __cplusplus >= 201103L
+ constexpr T it2;
+#endif
}
}
diff --git a/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp b/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
index 75894a8..2ad927c 100644
--- a/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
+++ b/test/std/iterators/stream.iterators/istreambuf.iterator/types.pass.cpp
@@ -22,6 +22,9 @@
// typedef basic_streambuf<charT,traits> streambuf_type;
// typedef basic_istream<charT,traits> istream_type;
// ...
+//
+// All specializations of istreambuf_iterator shall have a trivial copy constructor,
+// a constexpr default constructor and a trivial destructor.
#include <iterator>
#include <string>
@@ -38,6 +41,9 @@
static_assert((std::is_same<I1::int_type, I1::traits_type::int_type>::value), "");
static_assert((std::is_same<I1::streambuf_type, std::streambuf>::value), "");
static_assert((std::is_same<I1::istream_type, std::istream>::value), "");
+ static_assert((std::is_nothrow_default_constructible<I1>::value), "" );
+ static_assert((std::is_trivially_copy_constructible<I1>::value), "" );
+ static_assert((std::is_trivially_destructible<I1>::value), "" );
typedef std::istreambuf_iterator<wchar_t> I2;
static_assert((std::is_convertible<I2,
@@ -48,4 +54,7 @@
static_assert((std::is_same<I2::int_type, I2::traits_type::int_type>::value), "");
static_assert((std::is_same<I2::streambuf_type, std::wstreambuf>::value), "");
static_assert((std::is_same<I2::istream_type, std::wistream>::value), "");
+ static_assert((std::is_nothrow_default_constructible<I2>::value), "" );
+ static_assert((std::is_trivially_copy_constructible<I2>::value), "" );
+ static_assert((std::is_trivially_destructible<I2>::value), "" );
}
diff --git a/test/std/language.support/support.dynamic/alloc.errors/new.handler/new_handler.pass.cpp b/test/std/language.support/support.dynamic/alloc.errors/new.handler/new_handler.pass.cpp
index 6b799a3..0d4524c 100644
--- a/test/std/language.support/support.dynamic/alloc.errors/new.handler/new_handler.pass.cpp
+++ b/test/std/language.support/support.dynamic/alloc.errors/new.handler/new_handler.pass.cpp
@@ -10,10 +10,14 @@
// test new_handler
#include <new>
+#include <type_traits>
+#include <cassert>
void f() {}
int main()
{
+ static_assert((std::is_same<std::new_handler, void(*)()>::value), "");
std::new_handler p = f;
+ assert(p == &f);
}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
index 052d88f..a1a3035 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
@@ -9,7 +9,7 @@
// test operator new[]
// NOTE: asan and msan will not call the new handler.
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
@@ -38,7 +38,8 @@
std::set_new_handler(new_handler);
try
{
- void*volatile vp = operator new[] (std::numeric_limits<std::size_t>::max());
+ void* volatile vp = operator new[] (std::numeric_limits<std::size_t>::max());
+ ((void)vp);
assert(false);
}
catch (std::bad_alloc&)
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
index 259f5b0..b0db4a8 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
@@ -9,7 +9,7 @@
// test operator new [] (nothrow)
// NOTE: asan and msan will not call the new handler.
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
index 3e3a00c..105c7a9 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
@@ -9,7 +9,7 @@
// test operator new [] nothrow by replacing only operator new
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
#include <cstddef>
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
index acf972b..92bd7b9 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
@@ -9,7 +9,7 @@
// test operator new[] replacement by replacing only operator new
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
#include <cstddef>
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp
deleted file mode 100644
index 57e6cd6..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test sized operator delete[] by replacing unsized operator delete[].
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int delete_called = 0;
-int delete_nothrow_called = 0;
-
-void operator delete[](void* p) throw()
-{
- ++delete_called;
- delete_nothrow_called;
- std::free(p);
-}
-
-void operator delete[](void* p, const std::nothrow_t&) throw()
-{
- ++delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-int A_constructed = 0;
-
-struct A
-{
- A() {++A_constructed;}
- ~A() {--A_constructed;}
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void* vp = operator new [] (std::numeric_limits<std::size_t>::max());
- assert(false);
- }
- catch (std::bad_alloc&)
- {
- assert(new_handler_called == 1);
- }
- catch (...)
- {
- assert(false);
- }
- A* ap = new A[3];
- assert(ap);
- assert(A_constructed == 3);
- assert(!delete_called);
- assert(!delete_nothrow_called);
- delete [] ap;
- assert(A_constructed == 0);
- assert(delete_called == 1);
- assert(!delete_nothrow_called);
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array11.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array11.pass.cpp
new file mode 100644
index 0000000..0f7840c
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array11.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete[] replacement.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: c++14, c++1z
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int sized_delete_called = 0;
+
+void operator delete[](void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, std::size_t) throw()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+// NOTE: Use a class with a non-trivial destructor as the test type in order
+// to ensure the correct overload is called.
+// C++14 5.3.5 [expr.delete]p10
+// - If the type is complete and if, for the second alternative (delete array)
+// only, the operand is a pointer to a class type with a non-trivial
+// destructor or a (possibly multi-dimensional) array thereof, the function
+// with two parameters is selected.
+// - Otherwise, it is unspecified which of the two deallocation functions is
+// selected.
+struct A { ~A() {} };
+
+int main()
+{
+
+ A* x = new A[3];
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == sized_delete_called);
+
+ delete [] x;
+ assert(1 == unsized_delete_called);
+ assert(0 == sized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp
new file mode 100644
index 0000000..0e2cc6d
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array14.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete[] replacement.
+
+// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11
+
+// NOTE: Clang does not enable sized-deallocation in c++14 and beyond by
+// default. It is only enabled when -fsized-deallocation is given.
+// (except clang-3.6 which temporarily enabled sized-deallocation)
+// UNSUPPORTED: clang, apple-clang
+
+// NOTE: GCC 4.9.1 does not support sized-deallocation in c++14. However
+// GCC 5.1 does.
+// XFAIL: gcc-4.7, gcc-4.8, gcc-4.9
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int sized_delete_called = 0;
+
+void operator delete[](void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, std::size_t) throw()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+// NOTE: Use a class with a non-trivial destructor as the test type in order
+// to ensure the correct overload is called.
+// C++14 5.3.5 [expr.delete]p10
+// - If the type is complete and if, for the second alternative (delete array)
+// only, the operand is a pointer to a class type with a non-trivial
+// destructor or a (possibly multi-dimensional) array thereof, the function
+// with two parameters is selected.
+// - Otherwise, it is unspecified which of the two deallocation functions is
+// selected.
+struct A { ~A() {} };
+
+int main()
+{
+ A* x = new A[3];
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == sized_delete_called);
+
+ delete [] x;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(1 == sized_delete_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp
new file mode 100644
index 0000000..6d24aec
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator [] delete calls the unsized operator [] delete.
+// When sized operator delete [] is not available (ex C++11) then the unsized
+// operator delete [] is called directly.
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int delete_called = 0;
+int delete_nothrow_called = 0;
+
+void operator delete[](void* p) throw()
+{
+ ++delete_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, const std::nothrow_t&) throw()
+{
+ ++delete_nothrow_called;
+ std::free(p);
+}
+
+// NOTE: Use a class with a non-trivial destructor as the test type in order
+// to ensure the correct overload is called.
+// C++14 5.3.5 [expr.delete]p10
+// - If the type is complete and if, for the second alternative (delete array)
+// only, the operand is a pointer to a class type with a non-trivial
+// destructor or a (possibly multi-dimensional) array thereof, the function
+// with two parameters is selected.
+// - Otherwise, it is unspecified which of the two deallocation functions is
+// selected.
+struct A { ~A() {} };
+
+int main()
+{
+ A* x = new A[3];
+ assert(0 == delete_called);
+ assert(0 == delete_nothrow_called);
+
+ delete [] x;
+ assert(1 == delete_called);
+ assert(0 == delete_nothrow_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp
new file mode 100644
index 0000000..7dd510b
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_fsizeddeallocation.sh.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete[] replacement.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: sanitizer-new-delete
+
+// NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation.
+// REQUIRES: fsized-deallocation
+
+// RUN: %build -fsized-deallocation
+// RUN: %run
+
+#if !defined(__cpp_sized_deallocation)
+# error __cpp_sized_deallocation should be defined
+#endif
+
+#if !(__cpp_sized_deallocation >= 201309L)
+# error expected __cpp_sized_deallocation >= 201309L
+#endif
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int sized_delete_called = 0;
+
+void operator delete[](void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete[](void* p, std::size_t) throw()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+// NOTE: Use a class with a non-trivial destructor as the test type in order
+// to ensure the correct overload is called.
+// C++14 5.3.5 [expr.delete]p10
+// - If the type is complete and if, for the second alternative (delete array)
+// only, the operand is a pointer to a class type with a non-trivial
+// destructor or a (possibly multi-dimensional) array thereof, the function
+// with two parameters is selected.
+// - Otherwise, it is unspecified which of the two deallocation functions is
+// selected.
+struct A { ~A() {} };
+
+int main()
+{
+ A* x = new A[3];
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == sized_delete_called);
+
+ delete [] x;
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(1 == sized_delete_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp
deleted file mode 100644
index 05dc013..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow.pass.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test nothrow sized operator delete[] by replacing
-// nothrow unsized operator delete[].
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int delete_called = 0;
-int delete_nothrow_called = 0;
-
-void operator delete[](void* p) throw()
-{
- ++delete_called;
- std::free(p);
-}
-
-void operator delete[](void* p, const std::nothrow_t&) throw()
-{
- ++delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
- A() {A_constructed = true;}
- ~A() {A_constructed = false;}
-};
-
-struct BadA : public A {
- BadA() { throw std::bad_alloc(); }
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void*volatile vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
- assert(new_handler_called == 1);
- assert(vp == 0);
- }
- catch (...)
- {
- assert(false);
- }
- try
- {
- A* ap = new(std::nothrow) BadA [3];
- assert(false);
- }
- catch (...)
- {
- assert(!A_constructed);
- assert(!delete_called);
- assert(delete_nothrow_called == 1);
- }
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp
deleted file mode 100644
index 6a5320b..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_nothrow_replace.pass.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test nothrow sized operator delete[] replacement.
-
-// Note that sized delete operator definitions below are simply ignored
-// when sized deallocation is not supported, e.g., prior to C++14.
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int unsized_delete_called = 0;
-int unsized_delete_nothrow_called = 0;
-int sized_delete_called = 0;
-int sized_delete_nothrow_called = 0;
-
-void operator delete[](void* p) throw()
-{
- ++unsized_delete_called;
- std::free(p);
-}
-
-void operator delete[](void* p, const std::nothrow_t&) throw()
-{
- ++unsized_delete_nothrow_called;
- std::free(p);
-}
-
-void operator delete[](void* p, std::size_t) throw()
-{
- ++sized_delete_called;
- std::free(p);
-}
-
-void operator delete[](void* p, std::size_t, const std::nothrow_t&) throw()
-{
- ++sized_delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
- A() {A_constructed = true;}
- ~A() {A_constructed = false;}
-};
-
-struct BadA : public A {
- BadA() { throw std::bad_alloc(); }
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void*volatile vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
- assert(new_handler_called == 1);
- assert(vp == 0);
- }
- catch (...)
- {
- assert(false);
- }
- try
- {
- A* ap = new(std::nothrow) BadA [3];
- assert(false);
- }
- catch (...)
- {
- assert(!A_constructed);
-#if _LIBCPP_STD_VER >= 14
- // FIXME: Do we need a version of [Expr.Delete]#10 for nothrow
- // deallocation functions (selecting sized ones whenever available)?
- // It is not required by the standard. If it were, the following would
- // be the expected behaviour (instead of the current one):
- // assert(!unsized_delete_nothrow_called);
- // assert(sized_delete_nothrow_called == 1);
- assert(unsized_delete_nothrow_called == 1);
- assert(!sized_delete_nothrow_called);
-#else // if _LIBCPP_STD_VER < 14
- assert(unsized_delete_nothrow_called == 1);
- assert(!sized_delete_nothrow_called);
-#endif
- assert(!unsized_delete_called);
- assert(!sized_delete_called);
- }
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp
deleted file mode 100644
index 752cd70..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_replace.pass.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test sized operator delete[] replacement.
-
-// Note that sized delete operator definitions below are simply ignored
-// when sized deallocation is not supported, e.g., prior to C++14.
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int unsized_delete_called = 0;
-int unsized_delete_nothrow_called = 0;
-int sized_delete_called = 0;
-int sized_delete_nothrow_called = 0;
-
-void operator delete[](void* p) throw()
-{
- ++unsized_delete_called;
- std::free(p);
-}
-
-void operator delete[](void* p, const std::nothrow_t&) throw()
-{
- ++unsized_delete_nothrow_called;
- std::free(p);
-}
-
-void operator delete[](void* p, std::size_t) throw()
-{
- ++sized_delete_called;
- std::free(p);
-}
-
-void operator delete[](void* p, std::size_t, const std::nothrow_t&) throw()
-{
- ++sized_delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-int A_constructed = 0;
-
-struct A
-{
- A() {++A_constructed;}
- ~A() {--A_constructed;}
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void* vp = operator new [] (std::numeric_limits<std::size_t>::max());
- assert(false);
- }
- catch (std::bad_alloc&)
- {
- assert(new_handler_called == 1);
- }
- catch (...)
- {
- assert(false);
- }
- A* ap = new A[3];
- assert(ap);
- assert(A_constructed == 3);
- assert(!unsized_delete_called);
- assert(!unsized_delete_nothrow_called);
- assert(!sized_delete_called);
- assert(!sized_delete_nothrow_called);
- delete [] ap;
- assert(A_constructed == 0);
-#if _LIBCPP_STD_VER >= 14
- assert(!unsized_delete_called);
- assert(sized_delete_called == 1);
-#else // if _LIBCPP_STD_VER < 14
- assert(unsized_delete_called == 1);
- assert(!sized_delete_called);
-#endif
- assert(!unsized_delete_nothrow_called);
- assert(!sized_delete_nothrow_called);
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
index 3ba71dd..5dc9f71 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
@@ -10,7 +10,7 @@
// test operator new
// asan and msan will not call the new handler.
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
#include <cstddef>
@@ -39,6 +39,7 @@
try
{
void* vp = operator new (std::numeric_limits<std::size_t>::max());
+ ((void)vp);
assert(false);
}
catch (std::bad_alloc&)
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
index c76bfa0..8c095ad 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
@@ -10,7 +10,7 @@
// test operator new (nothrow)
// asan and msan will not call the new handler.
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
#include <cstddef>
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
index f2dbb98..cd70f90 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
@@ -9,7 +9,7 @@
// test operator new nothrow by replacing only operator new
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
#include <cstddef>
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
index 2d411b9..0df3a93 100644
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
@@ -9,7 +9,7 @@
// test operator new replacement
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <new>
#include <cstddef>
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp
deleted file mode 100644
index 6e3a235..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test sized operator delete by replacing unsized operator delete.
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int delete_called = 0;
-int delete_nothrow_called = 0;
-
-void operator delete(void* p) throw()
-{
- ++delete_called;
- delete_nothrow_called;
- std::free(p);
-}
-
-void operator delete(void* p, const std::nothrow_t&) throw()
-{
- ++delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
- A() {A_constructed = true;}
- ~A() {A_constructed = false;}
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void* vp = operator new (std::numeric_limits<std::size_t>::max());
- assert(false);
- }
- catch (std::bad_alloc&)
- {
- assert(new_handler_called == 1);
- }
- catch (...)
- {
- assert(false);
- }
- A* ap = new A;
- assert(ap);
- assert(A_constructed);
- assert(!delete_called);
- assert(!delete_nothrow_called);
- delete ap;
- assert(!A_constructed);
- assert(delete_called == 1);
- assert(!delete_nothrow_called);
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp
new file mode 100644
index 0000000..e4064e2
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete11.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete replacement.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: c++14, c++1z
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int sized_delete_called = 0;
+
+void operator delete(void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete(void* p, std::size_t) throw()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+int main()
+{
+ int *x = new int(42);
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == sized_delete_called);
+
+ delete x;
+ assert(1 == unsized_delete_called);
+ assert(0 == sized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp
new file mode 100644
index 0000000..5d9ddd4
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete14.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete replacement.
+
+// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11
+
+// NOTE: Clang does not enable sized-deallocation in c++14 and beyond by
+// default. It is only enabled when -fsized-deallocation is given.
+// (except clang-3.6 which temporarily enabled sized-deallocation)
+// UNSUPPORTED: clang, apple-clang
+
+// NOTE: GCC 4.9.1 does not support sized-deallocation in c++14. However
+// GCC 5.1 does.
+// XFAIL: gcc-4.7, gcc-4.8, gcc-4.9
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int sized_delete_called = 0;
+
+void operator delete(void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete(void* p, std::size_t) throw()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+int main()
+{
+ int *x = new int(42);
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+ assert(0 == sized_delete_called);
+
+ delete x;
+ assert(0 == unsized_delete_called);
+ assert(1 == sized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp
new file mode 100644
index 0000000..5c4eba5
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete calls the unsized operator delete.
+// When sized operator delete is not available (ex C++11) then the unsized
+// operator delete is called directly.
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int delete_called = 0;
+int delete_nothrow_called = 0;
+
+void operator delete(void* p) throw()
+{
+ ++delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ ++delete_nothrow_called;
+ std::free(p);
+}
+
+int main()
+{
+ int *x = new int(42);
+ assert(0 == delete_called);
+ assert(0 == delete_nothrow_called);
+
+ delete x;
+ assert(1 == delete_called);
+ assert(0 == delete_nothrow_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp
new file mode 100644
index 0000000..da43d49
--- /dev/null
+++ b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_fsizeddeallocation.sh.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test sized operator delete replacement.
+
+// Note that sized delete operator definitions below are simply ignored
+// when sized deallocation is not supported, e.g., prior to C++14.
+
+// UNSUPPORTED: sanitizer-new-delete
+
+// NOTE: Only clang-3.7 and GCC 5.1 and greater support -fsized-deallocation.
+// REQUIRES: fsized-deallocation
+
+// RUN: %build -fsized-deallocation
+// RUN: %run
+
+#if !defined(__cpp_sized_deallocation)
+# error __cpp_sized_deallocation should be defined
+#endif
+
+#if !(__cpp_sized_deallocation >= 201309L)
+# error expected __cpp_sized_deallocation >= 201309L
+#endif
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int sized_delete_called = 0;
+
+void operator delete(void* p) throw()
+{
+ ++unsized_delete_called;
+ std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ ++unsized_delete_nothrow_called;
+ std::free(p);
+}
+
+void operator delete(void* p, std::size_t) throw()
+{
+ ++sized_delete_called;
+ std::free(p);
+}
+
+int main()
+{
+ int *x = new int(42);
+ assert(0 == sized_delete_called);
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+
+ delete x;
+ assert(1 == sized_delete_called);
+ assert(0 == unsized_delete_called);
+ assert(0 == unsized_delete_nothrow_called);
+}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp
deleted file mode 100644
index 690e8af..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow.pass.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test nothrow sized operator delete by replacing
-// nothrow unsized operator delete.
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int delete_called = 0;
-int delete_nothrow_called = 0;
-
-void operator delete(void* p) throw()
-{
- ++delete_called;
- std::free(p);
-}
-
-void operator delete(void* p, const std::nothrow_t&) throw()
-{
- ++delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
- A() {A_constructed = true;}
- ~A() {A_constructed = false;}
-};
-
-struct BadA : public A {
- BadA() { throw std::bad_alloc(); }
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void* volatile vp = operator new (std::numeric_limits<std::size_t>::max(), std::nothrow);
- assert(new_handler_called == 1);
- assert(vp == 0);
- }
- catch (...)
- {
- assert(false);
- }
- try
- {
- A* ap = new(std::nothrow) BadA;
- assert(false);
- }
- catch (...)
- {
- assert(!A_constructed);
- assert(!delete_called);
- assert(delete_nothrow_called == 1);
- }
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp
deleted file mode 100644
index b5eb9f2..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_nothrow_replace.pass.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test nothrow sized operator delete replacement.
-
-// Note that sized delete operator definitions below are simply ignored
-// when sized deallocation is not supported, e.g., prior to C++14.
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int unsized_delete_called = 0;
-int unsized_delete_nothrow_called = 0;
-int sized_delete_called = 0;
-int sized_delete_nothrow_called = 0;
-
-void operator delete(void* p) throw()
-{
- ++unsized_delete_called;
- std::free(p);
-}
-
-void operator delete(void* p, const std::nothrow_t&) throw()
-{
- ++unsized_delete_nothrow_called;
- std::free(p);
-}
-
-void operator delete(void* p, std::size_t) throw()
-{
- ++sized_delete_called;
- std::free(p);
-}
-
-void operator delete(void* p, std::size_t, const std::nothrow_t&) throw()
-{
- ++sized_delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
- A() {A_constructed = true;}
- ~A() {A_constructed = false;}
-};
-
-struct BadA : public A {
- BadA() { throw std::bad_alloc(); }
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void*volatile vp = operator new (std::numeric_limits<std::size_t>::max(), std::nothrow);
- assert(new_handler_called == 1);
- assert(vp == 0);
- }
- catch (...)
- {
- assert(false);
- }
- try
- {
- A* ap = new(std::nothrow) BadA;
- assert(false);
- }
- catch (...)
- {
- assert(!A_constructed);
-#if _LIBCPP_STD_VER >= 14
- // FIXME: Do we need a version of [Expr.Delete]#10 for nothrow
- // deallocation functions (selecting sized ones whenever available)?
- // It is not required by the standard. If it were, the following would
- // be the expected behaviour (instead of the current one):
- // assert(!unsized_delete_nothrow_called);
- // assert(sized_delete_nothrow_called == 1);
- assert(unsized_delete_nothrow_called == 1);
- assert(!sized_delete_nothrow_called);
-#else // if _LIBCPP_STD_VER < 14
- assert(unsized_delete_nothrow_called == 1);
- assert(!sized_delete_nothrow_called);
-#endif
- assert(!unsized_delete_called);
- assert(!sized_delete_called);
- }
-}
diff --git a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp b/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp
deleted file mode 100644
index 4e0d7c7..0000000
--- a/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_replace.pass.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// test sized operator delete replacement.
-
-// Note that sized delete operator definitions below are simply ignored
-// when sized deallocation is not supported, e.g., prior to C++14.
-
-// UNSUPPORTED: asan, msan
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-int unsized_delete_called = 0;
-int unsized_delete_nothrow_called = 0;
-int sized_delete_called = 0;
-int sized_delete_nothrow_called = 0;
-
-void operator delete(void* p) throw()
-{
- ++unsized_delete_called;
- std::free(p);
-}
-
-void operator delete(void* p, const std::nothrow_t&) throw()
-{
- ++unsized_delete_nothrow_called;
- std::free(p);
-}
-
-void operator delete(void* p, std::size_t) throw()
-{
- ++sized_delete_called;
- std::free(p);
-}
-
-void operator delete(void* p, std::size_t, const std::nothrow_t&) throw()
-{
- ++sized_delete_nothrow_called;
- std::free(p);
-}
-
-int new_handler_called = 0;
-
-void new_handler()
-{
- ++new_handler_called;
- std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
- A() {A_constructed = true;}
- ~A() {A_constructed = false;}
-};
-
-int main()
-{
- std::set_new_handler(new_handler);
- try
- {
- void* vp = operator new (std::numeric_limits<std::size_t>::max());
- assert(false);
- }
- catch (std::bad_alloc&)
- {
- assert(new_handler_called == 1);
- }
- catch (...)
- {
- assert(false);
- }
- A* ap = new A;
- assert(ap);
- assert(A_constructed);
- assert(!unsized_delete_called);
- assert(!unsized_delete_nothrow_called);
- assert(!sized_delete_called);
- assert(!sized_delete_nothrow_called);
- delete ap;
- assert(!A_constructed);
-#if _LIBCPP_STD_VER >= 14
- assert(!unsized_delete_called);
- assert(sized_delete_called == 1);
-#else // if _LIBCPP_STD_VER < 14
- assert(unsized_delete_called == 1);
- assert(!sized_delete_called);
-#endif
- assert(!unsized_delete_nothrow_called);
- assert(!sized_delete_nothrow_called);
-}
diff --git a/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp b/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
index 887264a..dad0df2 100644
--- a/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
+++ b/test/std/language.support/support.exception/except.nested/throw_with_nested.pass.cpp
@@ -36,6 +36,10 @@
friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;}
};
+#if __cplusplus > 201103L
+struct Final final {};
+#endif
+
int main()
{
{
@@ -100,4 +104,16 @@
assert(i == 7);
}
}
+#if __cplusplus > 201103L
+ {
+ try
+ {
+ std::throw_with_nested(Final());
+ assert(false);
+ }
+ catch (const Final &f)
+ {
+ }
+ }
+#endif
}
diff --git a/test/std/language.support/support.exception/exception.terminate/terminate.handler/terminate_handler.pass.cpp b/test/std/language.support/support.exception/exception.terminate/terminate.handler/terminate_handler.pass.cpp
index 232ce0a..e477f52 100644
--- a/test/std/language.support/support.exception/exception.terminate/terminate.handler/terminate_handler.pass.cpp
+++ b/test/std/language.support/support.exception/exception.terminate/terminate.handler/terminate_handler.pass.cpp
@@ -10,10 +10,14 @@
// test terminate_handler
#include <exception>
+#include <type_traits>
+#include <cassert>
void f() {}
int main()
{
+ static_assert((std::is_same<std::terminate_handler, void(*)()>::value), "");
std::terminate_handler p = f;
+ assert(p == &f);
}
diff --git a/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp b/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
new file mode 100644
index 0000000..1adc904
--- /dev/null
+++ b/test/std/language.support/support.exception/uncaught/uncaught_exceptions.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// test uncaught_exceptions
+
+#include <exception>
+#include <cassert>
+
+struct A
+{
+ ~A()
+ {
+ assert(std::uncaught_exceptions() > 0);
+ }
+};
+
+struct B
+{
+ B()
+ {
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#475
+ assert(std::uncaught_exceptions() == 0);
+ }
+};
+
+int main()
+{
+ try
+ {
+ A a;
+ assert(std::uncaught_exceptions() == 0);
+ throw B();
+ }
+ catch (...)
+ {
+ assert(std::uncaught_exception() == 0);
+ }
+ assert(std::uncaught_exceptions() == 0);
+}
diff --git a/test/std/language.support/support.runtime/csignal.pass.cpp b/test/std/language.support/support.runtime/csignal.pass.cpp
index 717347d..a42363f 100644
--- a/test/std/language.support/support.runtime/csignal.pass.cpp
+++ b/test/std/language.support/support.runtime/csignal.pass.cpp
@@ -50,7 +50,8 @@
int main()
{
- std::sig_atomic_t sig;
+ std::sig_atomic_t sig = 0;
+ ((void)sig);
typedef void (*func)(int);
static_assert((std::is_same<decltype(std::signal(0, (func)0)), func>::value), "");
static_assert((std::is_same<decltype(std::raise(0)), int>::value), "");
diff --git a/test/std/language.support/support.runtime/cstdarg.pass.cpp b/test/std/language.support/support.runtime/cstdarg.pass.cpp
index 059ad2f..9d6f610 100644
--- a/test/std/language.support/support.runtime/cstdarg.pass.cpp
+++ b/test/std/language.support/support.runtime/cstdarg.pass.cpp
@@ -32,4 +32,5 @@
int main()
{
std::va_list va;
+ ((void)va);
}
diff --git a/test/std/language.support/support.runtime/cstdlib.pass.cpp b/test/std/language.support/support.runtime/cstdlib.pass.cpp
index e14e70e..8191350 100644
--- a/test/std/language.support/support.runtime/cstdlib.pass.cpp
+++ b/test/std/language.support/support.runtime/cstdlib.pass.cpp
@@ -11,6 +11,7 @@
#include <cstdlib>
#include <type_traits>
+#include <cassert>
#ifndef EXIT_FAILURE
#error EXIT_FAILURE not defined
@@ -32,12 +33,23 @@
#error RAND_MAX not defined
#endif
+template <class TestType, class IntType>
+void test_div_struct() {
+ TestType obj;
+ static_assert(sizeof(obj) >= sizeof(IntType) * 2, ""); // >= to account for alignment.
+ static_assert((std::is_same<decltype(obj.quot), IntType>::value), "");
+ static_assert((std::is_same<decltype(obj.rem), IntType>::value), "");
+ ((void) obj);
+};
+
int main()
{
std::size_t s = 0;
- std::div_t d;
- std::ldiv_t ld;
- std::lldiv_t lld;
+ ((void)s);
+ static_assert((std::is_same<std::size_t, decltype(sizeof(int))>::value), "");
+ test_div_struct<std::div_t, int>();
+ test_div_struct<std::ldiv_t, long>();
+ test_div_struct<std::lldiv_t, long long>();
char** endptr = 0;
static_assert((std::is_same<decltype(std::atof("")), double>::value), "");
static_assert((std::is_same<decltype(std::atoi("")), int>::value), "");
@@ -75,12 +87,14 @@
static_assert((std::is_same<decltype(std::div(0LL,0LL)), std::lldiv_t>::value), "");
static_assert((std::is_same<decltype(std::ldiv(0L,0L)), std::ldiv_t>::value), "");
static_assert((std::is_same<decltype(std::lldiv(0LL,0LL)), std::lldiv_t>::value), "");
- static_assert((std::is_same<decltype(std::mblen("",0)), int>::value), "");
wchar_t* pw = 0;
const wchar_t* pwc = 0;
char* pc = 0;
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+ static_assert((std::is_same<decltype(std::mblen("",0)), int>::value), "");
static_assert((std::is_same<decltype(std::mbtowc(pw,"",0)), int>::value), "");
static_assert((std::is_same<decltype(std::wctomb(pc,L' ')), int>::value), "");
+#endif
static_assert((std::is_same<decltype(std::mbstowcs(pw,"",0)), std::size_t>::value), "");
static_assert((std::is_same<decltype(std::wcstombs(pc,pwc,0)), std::size_t>::value), "");
}
diff --git a/test/std/language.support/support.runtime/ctime.pass.cpp b/test/std/language.support/support.runtime/ctime.pass.cpp
index 495d6eb..03a0aa4 100644
--- a/test/std/language.support/support.runtime/ctime.pass.cpp
+++ b/test/std/language.support/support.runtime/ctime.pass.cpp
@@ -23,6 +23,7 @@
int main()
{
std::clock_t c = 0;
+ ((void)c);
std::size_t s = 0;
std::time_t t = 0;
std::tm tm = {0};
@@ -30,10 +31,12 @@
static_assert((std::is_same<decltype(std::difftime(t,t)), double>::value), "");
static_assert((std::is_same<decltype(std::mktime(&tm)), std::time_t>::value), "");
static_assert((std::is_same<decltype(std::time(&t)), std::time_t>::value), "");
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
static_assert((std::is_same<decltype(std::asctime(&tm)), char*>::value), "");
static_assert((std::is_same<decltype(std::ctime(&t)), char*>::value), "");
static_assert((std::is_same<decltype(std::gmtime(&t)), std::tm*>::value), "");
static_assert((std::is_same<decltype(std::localtime(&t)), std::tm*>::value), "");
+#endif
char* c1 = 0;
const char* c2 = 0;
static_assert((std::is_same<decltype(std::strftime(c1,s,c2,&tm)), std::size_t>::value), "");
diff --git a/test/std/localization/c.locales/clocale.pass.cpp b/test/std/localization/c.locales/clocale.pass.cpp
index 3b3e933..a90725b 100644
--- a/test/std/localization/c.locales/clocale.pass.cpp
+++ b/test/std/localization/c.locales/clocale.pass.cpp
@@ -12,6 +12,8 @@
#include <clocale>
#include <type_traits>
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+
#ifndef LC_ALL
#error LC_ALL not defined
#endif
@@ -36,6 +38,8 @@
#error LC_TIME not defined
#endif
+#endif // !_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+
#ifndef NULL
#error NULL not defined
#endif
@@ -43,6 +47,8 @@
int main()
{
std::lconv lc;
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
static_assert((std::is_same<decltype(std::setlocale(0, "")), char*>::value), "");
+#endif
static_assert((std::is_same<decltype(std::localeconv()), std::lconv*>::value), "");
}
diff --git a/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp
new file mode 100644
index 0000000..a09072a
--- /dev/null
+++ b/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/mask.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <locale>
+
+// template <class charT> class ctype_byname;
+
+// bool is(mask m, charT c) const;
+
+#include <locale>
+#include <type_traits>
+#include <cassert>
+
+int main()
+{
+ {
+ std::locale l("C");
+ {
+ typedef std::ctype<wchar_t> WF;
+ const WF& wf = std::use_facet<WF>(l);
+ typedef std::ctype<char> CF;
+ const CF& cf = std::use_facet<CF>(l);
+
+ // The ctype masks in Newlib don't form a proper bitmask because
+ // the mask is only 8 bits wide, and there are more than 8 mask
+ // kinds. This means that the mask for alpha is (_U | _L), which
+ // is tricky to match in the do_is implementation because in
+ // [22.4.1.1.2 2] the standard specifies that the match code behaves
+ // like (m & M) != 0, but following this exactly would give false
+ // positives for characters that are both 'upper' and 'alpha', but
+ // not 'lower', for example.
+ assert( wf.is(WF::upper, L'A'));
+ assert( cf.is(CF::upper, 'A'));
+ assert(!wf.is(WF::lower, L'A'));
+ assert(!cf.is(CF::lower, 'A'));
+ assert( wf.is(WF::alpha, L'A'));
+ assert( cf.is(CF::alpha, 'A'));
+
+ assert(!wf.is(WF::upper, L'a'));
+ assert(!cf.is(CF::upper, 'a'));
+ assert( wf.is(WF::lower, L'a'));
+ assert( cf.is(CF::lower, 'a'));
+ assert( wf.is(WF::alpha, L'a'));
+ assert( cf.is(CF::alpha, 'a'));
+ }
+ }
+}
diff --git a/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp b/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
index 427d7c5..d9e7f3c 100644
--- a/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
+++ b/test/std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp
@@ -14,9 +14,6 @@
// iter_type put(iter_type s, ios_base& str, char_type fill, const tm* t,
// char format, char modifier = 0) const;
-// TODO: investigation needed
-// XFAIL: linux-gnu
-
#include <locale>
#include <cassert>
#include "test_iterators.h"
@@ -36,7 +33,7 @@
const my_facet f(1);
char str[200];
output_iterator<char*> iter;
- tm t = {0};
+ tm t = {};
t.tm_sec = 6;
t.tm_min = 3;
t.tm_hour = 13;
@@ -44,7 +41,7 @@
t.tm_mon = 4;
t.tm_year = 109;
t.tm_wday = 6;
- t.tm_yday = -1;
+ t.tm_yday = 121;
t.tm_isdst = 1;
std::ios ios(0);
{
@@ -160,12 +157,12 @@
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'U', 'O');
std::string ex(str, iter.base());
- assert(ex == "00");
+ assert(ex == "17");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'V', 'O');
std::string ex(str, iter.base());
- assert(ex == "52");
+ assert(ex == "18");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'w', 'O');
@@ -175,7 +172,7 @@
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'W', 'O');
std::string ex(str, iter.base());
- assert(ex == "00");
+ assert(ex == "17");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'y', 'O');
@@ -183,11 +180,6 @@
assert(ex == "09");
}
{
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'B', 'O');
- std::string ex(str, iter.base());
- assert(ex == "May");
- }
- {
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'e');
std::string ex(str, iter.base());
assert(ex == " 2");
@@ -200,12 +192,12 @@
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'G');
std::string ex(str, iter.base());
- assert(ex == "2008");
+ assert(ex == "2009");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'g');
std::string ex(str, iter.base());
- assert(ex == "08");
+ assert(ex == "09");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'H');
@@ -225,17 +217,7 @@
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'j');
std::string ex(str, iter.base());
- assert(ex == "000");
- }
- {
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'k');
- std::string ex(str, iter.base());
- assert(ex == "13");
- }
- {
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'l');
- std::string ex(str, iter.base());
- assert(ex == " 1");
+ assert(ex == "122");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'M');
@@ -273,11 +255,6 @@
assert(ex == "06");
}
{
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, 's');
- std::string ex(str, iter.base());
-// assert(ex == "1241283786"); depends on time zone
- }
- {
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'T');
std::string ex(str, iter.base());
assert(ex == "13:03:06");
@@ -290,7 +267,7 @@
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'U');
std::string ex(str, iter.base());
- assert(ex == "00");
+ assert(ex == "17");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'u');
@@ -300,17 +277,12 @@
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'V');
std::string ex(str, iter.base());
- assert(ex == "52");
- }
- {
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'v');
- std::string ex(str, iter.base());
- assert(ex == " 2-May-2009");
+ assert(ex == "18");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'W');
std::string ex(str, iter.base());
- assert(ex == "00");
+ assert(ex == "17");
}
{
iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'w');
@@ -357,14 +329,4 @@
std::string ex(str, iter.base());
assert(ex == "%");
}
- {
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, '%', 'J');
- std::string ex(str, iter.base());
- assert(ex == "J%");
- }
- {
- iter = f.put(output_iterator<char*>(str), ios, '*', &t, 'J');
- std::string ex(str, iter.base());
- assert(ex == "J");
- }
}
diff --git a/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/lit.local.cfg b/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/lit.local.cfg
new file mode 100644
index 0000000..25ac02b
--- /dev/null
+++ b/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/lit.local.cfg
@@ -0,0 +1,2 @@
+if 'libcpp-has-no-global-filesystem-namespace' in config.available_features:
+ config.unsupported = True
diff --git a/test/std/localization/locales/locale/locale.cons/assign.pass.cpp b/test/std/localization/locales/locale/locale.cons/assign.pass.cpp
index 75ce9b5..80afe1e 100644
--- a/test/std/localization/locales/locale/locale.cons/assign.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/assign.pass.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: locale.ru_RU.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp b/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp
index 01857a4..3567bf5 100644
--- a/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/char_pointer.pass.cpp
@@ -9,7 +9,7 @@
// REQUIRES: locale.ru_RU.UTF-8
// REQUIRES: locale.zh_CN.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/copy.pass.cpp b/test/std/localization/locales/locale/locale.cons/copy.pass.cpp
index 629c9e6..0760cc4 100644
--- a/test/std/localization/locales/locale/locale.cons/copy.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/copy.pass.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: locale.fr_FR.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
index eaadbb9..2a9e20f 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_char_pointer_cat.pass.cpp
@@ -9,7 +9,7 @@
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp
index 8b83bc0..fb6e39e 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_facetptr.pass.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: locale.ru_RU.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
index 05f0619..fa87eb2 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_locale_cat.pass.cpp
@@ -9,7 +9,7 @@
// REQUIRES: locale.en_US.UTF-8
// REQUIRES: locale.ru_RU.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp b/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
index 66be76d..d48a572 100644
--- a/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/locale_string_cat.pass.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: locale.ru_RU.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/localization/locales/locale/locale.cons/string.pass.cpp b/test/std/localization/locales/locale/locale.cons/string.pass.cpp
index 32c3507..c9f9441 100644
--- a/test/std/localization/locales/locale/locale.cons/string.pass.cpp
+++ b/test/std/localization/locales/locale/locale.cons/string.pass.cpp
@@ -9,7 +9,7 @@
// REQUIRES: locale.ru_RU.UTF-8
// REQUIRES: locale.zh_CN.UTF-8
-// UNSUPPORTED: msan, asan
+// UNSUPPORTED: sanitizer-new-delete
// <locale>
diff --git a/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp b/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp
index d46d91f..fcf075a 100644
--- a/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp
+++ b/test/std/numerics/cfenv/cfenv.syn/cfenv.pass.cpp
@@ -60,8 +60,8 @@
int main()
{
- std::fenv_t fenv = {0};
- std::fexcept_t fex = 0;
+ std::fenv_t fenv;
+ std::fexcept_t fex;
static_assert((std::is_same<decltype(std::feclearexcept(0)), int>::value), "");
static_assert((std::is_same<decltype(std::fegetexceptflag(&fex, 0)), int>::value), "");
static_assert((std::is_same<decltype(std::feraiseexcept(0)), int>::value), "");
diff --git a/test/std/numerics/rand/rand.device/ctor.pass.cpp b/test/std/numerics/rand/rand.device/ctor.pass.cpp
index 2d9bc2f..97f46b2 100644
--- a/test/std/numerics/rand/rand.device/ctor.pass.cpp
+++ b/test/std/numerics/rand/rand.device/ctor.pass.cpp
@@ -23,14 +23,12 @@
#include <unistd.h>
bool is_valid_random_device(const std::string &token) {
-#if defined(_WIN32)
- return true;
-#elif defined(_LIBCPP_USING_NACL_RANDOM)
- return token == "/dev/urandom";
-#else // !defined(_WIN32) && !defined(_LIBCPP_USING_NACL_RANDOM)
+#if defined(_LIBCPP_USING_DEV_RANDOM)
// Not an exhaustive list: they're the only tokens that are tested below.
return token == "/dev/urandom" || token == "/dev/random";
-#endif // defined(_WIN32) || defined(_LIBCPP_USING_NACL_RANDOM)
+#else
+ return token == "/dev/urandom";
+#endif
}
void check_random_device_valid(const std::string &token) {
diff --git a/test/std/re/re.alg/re.alg.match/awk.pass.cpp b/test/std/re/re.alg/re.alg.match/awk.pass.cpp
index d2065a0..e4b2f3e 100644
--- a/test/std/re/re.alg/re.alg.match/awk.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/awk.pass.cpp
@@ -19,9 +19,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
/* {
@@ -613,7 +614,7 @@
std::regex_constants::awk)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
*/ {
std::cmatch m;
const char s[] = "m";
@@ -1294,7 +1295,7 @@
std::regex_constants::awk)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.match/basic.pass.cpp b/test/std/re/re.alg/re.alg.match/basic.pass.cpp
index 4139cea..2ddc07a 100644
--- a/test/std/re/re.alg/re.alg.match/basic.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/basic.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -619,7 +620,7 @@
std::regex_constants::basic)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1287,7 +1288,7 @@
std::regex_constants::basic)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.match/ecma.pass.cpp b/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
index 3854056..785a61c 100644
--- a/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -581,7 +582,7 @@
assert(!std::regex_match(s, m, std::regex("[a[.hyphen.]z]")));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1246,7 +1247,7 @@
assert(!std::regex_match(s, m, std::wregex(L"[a[.hyphen.]z]")));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.match/extended.pass.cpp b/test/std/re/re.alg/re.alg.match/extended.pass.cpp
index c54825d..9ca31d1 100644
--- a/test/std/re/re.alg/re.alg.match/extended.pass.cpp
+++ b/test/std/re/re.alg/re.alg.match/extended.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -617,7 +618,7 @@
std::regex_constants::extended)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1283,7 +1284,7 @@
std::regex_constants::extended)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.search/awk.pass.cpp b/test/std/re/re.alg/re.alg.search/awk.pass.cpp
index 521e98b..7fc1b3f 100644
--- a/test/std/re/re.alg/re.alg.search/awk.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/awk.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -689,7 +690,7 @@
std::regex_constants::awk)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1460,7 +1461,7 @@
std::regex_constants::awk)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.search/basic.pass.cpp b/test/std/re/re.alg/re.alg.search/basic.pass.cpp
index 838294e..bdfcd9c 100644
--- a/test/std/re/re.alg/re.alg.search/basic.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/basic.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -691,7 +692,7 @@
std::regex_constants::basic)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1449,7 +1450,7 @@
std::regex_constants::basic)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.search/ecma.pass.cpp b/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
index 2796850..fb9fc26 100644
--- a/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -671,7 +672,7 @@
assert(!std::regex_search(s, m, std::regex("[a[.hyphen.]z]")));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1450,7 +1451,7 @@
assert(!std::regex_search(s, m, std::wregex(L"[a[.hyphen.]z]")));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.alg/re.alg.search/extended.pass.cpp b/test/std/re/re.alg/re.alg.search/extended.pass.cpp
index a8a121b..81eef2f 100644
--- a/test/std/re/re.alg/re.alg.search/extended.pass.cpp
+++ b/test/std/re/re.alg/re.alg.search/extended.pass.cpp
@@ -23,9 +23,10 @@
#include <regex>
#include <cassert>
-
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -689,7 +690,7 @@
std::regex_constants::extended)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::cmatch m;
const char s[] = "m";
@@ -1445,7 +1446,7 @@
std::regex_constants::extended)));
assert(m.size() == 0);
}
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
{
std::wcmatch m;
const wchar_t s[] = L"m";
diff --git a/test/std/re/re.const/re.matchflag/match_not_bol.pass.cpp b/test/std/re/re.const/re.matchflag/match_not_bol.pass.cpp
new file mode 100644
index 0000000..41ac0ce
--- /dev/null
+++ b/test/std/re/re.const/re.matchflag/match_not_bol.pass.cpp
@@ -0,0 +1,50 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// match_not_bol:
+// The first character in the sequence [first,last) shall be treated as
+// though it is not at the beginning of a line, so the character ^ in the
+// regular expression shall not match [first,first).
+
+#include <regex>
+#include <cassert>
+
+int main()
+{
+ {
+ std::string target = "foo";
+ std::regex re("^foo");
+ assert( std::regex_match(target, re));
+ assert(!std::regex_match(target, re, std::regex_constants::match_not_bol));
+ }
+
+ {
+ std::string target = "foo";
+ std::regex re("foo");
+ assert( std::regex_match(target, re));
+ assert( std::regex_match(target, re, std::regex_constants::match_not_bol));
+ }
+
+ {
+ std::string target = "fooby";
+ std::regex re("^foo");
+ assert( std::regex_search(target, re));
+ assert(!std::regex_search(target, re, std::regex_constants::match_not_bol));
+ }
+
+ {
+ std::string target = "fooby";
+ std::regex re("foo");
+ assert( std::regex_search(target, re));
+ assert( std::regex_search(target, re, std::regex_constants::match_not_bol));
+ }
+}
diff --git a/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp b/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp
new file mode 100644
index 0000000..594c9fb
--- /dev/null
+++ b/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp
@@ -0,0 +1,50 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// match_not_eol:
+// The last character in the sequence [first,last) shall be treated as
+// though it is not at the end of a line, so the character "$" in
+// the regular expression shall not match [last,last).
+
+#include <regex>
+#include <cassert>
+
+int main()
+{
+ {
+ std::string target = "foo";
+ std::regex re("foo$");
+ assert( std::regex_match(target, re));
+ assert(!std::regex_match(target, re, std::regex_constants::match_not_eol));
+ }
+
+ {
+ std::string target = "foo";
+ std::regex re("foo");
+ assert( std::regex_match(target, re));
+ assert( std::regex_match(target, re, std::regex_constants::match_not_eol));
+ }
+
+ {
+ std::string target = "refoo";
+ std::regex re("foo$");
+ assert( std::regex_search(target, re));
+ assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
+ }
+
+ {
+ std::string target = "refoo";
+ std::regex re("foo");
+ assert( std::regex_search(target, re));
+ assert( std::regex_search(target, re, std::regex_constants::match_not_eol));
+ }
+}
diff --git a/test/std/re/re.regex/re.regex.construct/bad_escape.pass.cpp b/test/std/re/re.regex/re.regex.construct/bad_escape.pass.cpp
index 9455527..ddf2607 100644
--- a/test/std/re/re.regex/re.regex.construct/bad_escape.pass.cpp
+++ b/test/std/re/re.regex/re.regex.construct/bad_escape.pass.cpp
@@ -22,7 +22,7 @@
bool result = false;
try {
std::regex re(pat);
- } catch (std::regex_error &ex) {
+ } catch (const std::regex_error &ex) {
result = (ex.code() == std::regex_constants::error_escape);
}
return result;
diff --git a/test/std/re/re.regex/re.regex.construct/bad_repeat.pass.cpp b/test/std/re/re.regex/re.regex.construct/bad_repeat.pass.cpp
new file mode 100644
index 0000000..bc70ec1
--- /dev/null
+++ b/test/std/re/re.regex/re.regex.construct/bad_repeat.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// template <class charT, class traits = regex_traits<charT>> class basic_regex;
+
+// template <class ST, class SA>
+// basic_regex(const basic_string<charT, ST, SA>& s);
+
+#include <regex>
+#include <cassert>
+
+static bool error_badrepeat_thrown(const char *pat)
+{
+ bool result = false;
+ try {
+ std::regex re(pat);
+ } catch (const std::regex_error &ex) {
+ result = (ex.code() == std::regex_constants::error_badrepeat);
+ }
+ return result;
+}
+
+int main()
+{
+ assert(error_badrepeat_thrown("?a"));
+ assert(error_badrepeat_thrown("*a"));
+ assert(error_badrepeat_thrown("+a"));
+ assert(error_badrepeat_thrown("{a"));
+
+ assert(error_badrepeat_thrown("?(a+)"));
+ assert(error_badrepeat_thrown("*(a+)"));
+ assert(error_badrepeat_thrown("+(a+)"));
+ assert(error_badrepeat_thrown("{(a+)"));
+}
diff --git a/test/std/re/re.traits/lookup_collatename.pass.cpp b/test/std/re/re.traits/lookup_collatename.pass.cpp
index d495f8a..a7cd5f0 100644
--- a/test/std/re/re.traits/lookup_collatename.pass.cpp
+++ b/test/std/re/re.traits/lookup_collatename.pass.cpp
@@ -25,6 +25,8 @@
#include <cassert>
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
template <class char_type>
void
test(const char_type* A, const std::basic_string<char_type>& expected)
@@ -108,7 +110,7 @@
test("tild", std::string(""));
test("ch", std::string(""));
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
test("ch", std::string("ch"));
std::locale::global(std::locale("C"));
@@ -184,7 +186,7 @@
test(L"tild", std::wstring(L""));
test(L"ch", std::wstring(L""));
- std::locale::global(std::locale("cs_CZ.ISO8859-2"));
+ std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
test(L"ch", std::wstring(L"ch"));
std::locale::global(std::locale("C"));
}
diff --git a/test/std/re/re.traits/transform.pass.cpp b/test/std/re/re.traits/transform.pass.cpp
index c3bce79..85235e0 100644
--- a/test/std/re/re.traits/transform.pass.cpp
+++ b/test/std/re/re.traits/transform.pass.cpp
@@ -21,6 +21,8 @@
#include <cassert>
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -29,7 +31,7 @@
const char B[] = "B";
typedef forward_iterator<const char*> F;
assert(t.transform(F(a), F(a+1)) > t.transform(F(B), F(B+1)));
- t.imbue(std::locale("cs_CZ.ISO8859-2"));
+ t.imbue(std::locale(LOCALE_cs_CZ_ISO8859_2));
assert(t.transform(F(a), F(a+1)) < t.transform(F(B), F(B+1)));
}
{
@@ -38,7 +40,7 @@
const wchar_t B[] = L"B";
typedef forward_iterator<const wchar_t*> F;
assert(t.transform(F(a), F(a+1)) > t.transform(F(B), F(B+1)));
- t.imbue(std::locale("cs_CZ.ISO8859-2"));
+ t.imbue(std::locale(LOCALE_cs_CZ_ISO8859_2));
assert(t.transform(F(a), F(a+1)) < t.transform(F(B), F(B+1)));
}
}
diff --git a/test/std/re/re.traits/transform_primary.pass.cpp b/test/std/re/re.traits/transform_primary.pass.cpp
index 28734d6..438cd75 100644
--- a/test/std/re/re.traits/transform_primary.pass.cpp
+++ b/test/std/re/re.traits/transform_primary.pass.cpp
@@ -22,6 +22,8 @@
#include <cassert>
#include "test_iterators.h"
+#include "platform_support.h" // locale name macros
+
int main()
{
{
@@ -31,7 +33,7 @@
typedef forward_iterator<const char*> F;
assert(t.transform_primary(F(A), F(A+1)) !=
t.transform_primary(F(Aacute), F(Aacute+1)));
- t.imbue(std::locale("cs_CZ.ISO8859-2"));
+ t.imbue(std::locale(LOCALE_cs_CZ_ISO8859_2));
assert(t.transform_primary(F(A), F(A+1)) ==
t.transform_primary(F(Aacute), F(Aacute+1)));
}
@@ -42,7 +44,7 @@
typedef forward_iterator<const wchar_t*> F;
assert(t.transform_primary(F(A), F(A+1)) !=
t.transform_primary(F(Aacute), F(Aacute+1)));
- t.imbue(std::locale("cs_CZ.ISO8859-2"));
+ t.imbue(std::locale(LOCALE_cs_CZ_ISO8859_2));
assert(t.transform_primary(F(A), F(A+1)) ==
t.transform_primary(F(Aacute), F(Aacute+1)));
}
diff --git a/test/std/strings/basic.string/string.capacity/max_size.pass.cpp b/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
index f426425..e4ff556 100644
--- a/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
+++ b/test/std/strings/basic.string/string.capacity/max_size.pass.cpp
@@ -16,7 +16,7 @@
// returns null.
// 2. If allocator_may_return_null=1 then they will fail because the allocation
// is too large to succeed.
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <string>
#include <cassert>
diff --git a/test/std/strings/basic.string/string.cons/alloc.pass.cpp b/test/std/strings/basic.string/string.cons/alloc.pass.cpp
index 512d118..1c4f204 100644
--- a/test/std/strings/basic.string/string.cons/alloc.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/alloc.pass.cpp
@@ -14,6 +14,7 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"
@@ -22,6 +23,11 @@
test()
{
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" );
+#endif
S s;
assert(s.__invariants());
assert(s.data());
@@ -30,6 +36,11 @@
assert(s.get_allocator() == typename S::allocator_type());
}
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{typename S::allocator_type{}})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S(typename S::allocator_type())) == std::is_nothrow_copy_constructible<typename S::allocator_type>::value), "" );
+#endif
S s(typename S::allocator_type(5));
assert(s.__invariants());
assert(s.data());
@@ -39,13 +50,18 @@
}
}
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
template <class S>
void
test2()
{
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S()) == noexcept(typename S::allocator_type())), "" );
+#endif
S s;
assert(s.__invariants());
assert(s.data());
@@ -54,6 +70,11 @@
assert(s.get_allocator() == typename S::allocator_type());
}
{
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{typename S::allocator_type{}})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S(typename S::allocator_type())) == std::is_nothrow_copy_constructible<typename S::allocator_type>::value), "" );
+#endif
S s(typename S::allocator_type{});
assert(s.__invariants());
assert(s.data());
@@ -68,7 +89,7 @@
int main()
{
test<std::basic_string<char, std::char_traits<char>, test_allocator<char> > >();
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
test2<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
#endif
}
diff --git a/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp
index f935db8..af11710 100644
--- a/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/default_noexcept.pass.cpp
@@ -17,6 +17,7 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "test_allocator.h"
template <class T>
diff --git a/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp b/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
index 1f96314..a232a46 100644
--- a/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/move_alloc.pass.cpp
@@ -16,6 +16,7 @@
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"
@@ -34,6 +35,11 @@
}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+// #if _LIBCPP_STD_VER <= 14
+// _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+// #else
+// _NOEXCEPT;
+// #endif
int main()
{
@@ -41,6 +47,11 @@
{
typedef test_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "" );
+#endif
test(S(), A(3));
test(S("1"), A(5));
test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
@@ -50,15 +61,25 @@
{
typedef test_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "" );
+#endif
S s1 ( "Twas brillig, and the slivy toves did gyre and gymbal in the wabe" );
S s2 (std::move(s1), A(1));
}
assert ( test_alloc_base::alloc_count == alloc_count );
-#if __cplusplus >= 201103L
+#if TEST_STD_VER >= 11
{
typedef min_allocator<char> A;
typedef std::basic_string<char, std::char_traits<char>, A> S;
+#if TEST_STD_VER > 14
+ static_assert((noexcept(S{})), "" );
+#elif TEST_STD_VER >= 11
+ static_assert((noexcept(S()) == std::is_nothrow_move_constructible<A>::value), "" );
+#endif
test(S(), A());
test(S("1"), A());
test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
diff --git a/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp b/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
index 556aabd..b287a94 100644
--- a/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
+++ b/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp
@@ -17,6 +17,7 @@
#include <string>
#include <cassert>
+#include "test_macros.h"
#include "test_allocator.h"
template <class T>
@@ -39,7 +40,11 @@
}
{
typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
+#if TEST_STD_VER <= 14
static_assert(!std::is_nothrow_move_constructible<C>::value, "");
+#else
+ static_assert( std::is_nothrow_move_constructible<C>::value, "");
+#endif
}
#endif
}
diff --git a/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp b/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp
index 4d5d796..cfe0365 100644
--- a/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp
+++ b/test/std/strings/basic.string/string.nonmembers/string.special/swap_noexcept.pass.cpp
@@ -12,6 +12,10 @@
// void swap(basic_string& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
// __is_nothrow_swappable<allocator_type>::value);
+//
+// In C++17, the standard says that swap shall have:
+// noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
+// allocator_traits<Allocator>::is_always_equal::value);
// This tests a conforming extension
@@ -32,6 +36,19 @@
typedef std::true_type propagate_on_container_swap;
};
+template <class T>
+struct some_alloc2
+{
+ typedef T value_type;
+
+ some_alloc2() {}
+ some_alloc2(const some_alloc2&);
+ void deallocate(void*, unsigned) {}
+
+ typedef std::false_type propagate_on_container_swap;
+ typedef std::true_type is_always_equal;
+};
+
int main()
{
#if __has_feature(cxx_noexcept)
@@ -48,7 +65,21 @@
{
typedef std::basic_string<char, std::char_traits<char>, some_alloc<char>> C;
C c1, c2;
+#if TEST_STD_VER >= 14
+ // In c++14, if POCS is set, swapping the allocator is required not to throw
+ static_assert( noexcept(swap(c1, c2)), "");
+#else
static_assert(!noexcept(swap(c1, c2)), "");
+#endif
}
+#if TEST_STD_VER >= 14
+ {
+ typedef std::basic_string<char, std::char_traits<char>, some_alloc2<char>> C;
+ C c1, c2;
+ // if the allocators are always equal, then the swap can be noexcept
+ static_assert( noexcept(swap(c1, c2)), "");
+ }
+#endif
+
#endif
}
diff --git a/test/std/strings/basic.string/string.require/contiguous.pass.cpp b/test/std/strings/basic.string/string.require/contiguous.pass.cpp
new file mode 100644
index 0000000..ca31ace
--- /dev/null
+++ b/test/std/strings/basic.string/string.require/contiguous.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// An string is a contiguous container
+
+#include <string>
+#include <cassert>
+
+#include "test_allocator.h"
+#include "min_allocator.h"
+
+
+template <class C>
+void test_contiguous ( const C &c )
+{
+ for ( size_t i = 0; i < c.size(); ++i )
+ assert ( *(c.begin() + i) == *(std::addressof(*c.begin()) + i));
+}
+
+int main()
+{
+ {
+ typedef std::string S;
+ test_contiguous(S());
+ test_contiguous(S("1"));
+ test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890"));
+ }
+
+ {
+ typedef test_allocator<char> A;
+ typedef std::basic_string<char, std::char_traits<char>, A> S;
+ test_contiguous(S(A(3)));
+ test_contiguous(S("1", A(5)));
+ test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)));
+ }
+#if __cplusplus >= 201103L
+ {
+ typedef min_allocator<char> A;
+ typedef std::basic_string<char, std::char_traits<char>, A> S;
+ test_contiguous(S(A{}));
+ test_contiguous(S("1", A()));
+ test_contiguous(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()));
+ }
+#endif
+}
diff --git a/test/std/strings/c.strings/cstring.pass.cpp b/test/std/strings/c.strings/cstring.pass.cpp
index 5ed7e6c..20f4050 100644
--- a/test/std/strings/c.strings/cstring.pass.cpp
+++ b/test/std/strings/c.strings/cstring.pass.cpp
@@ -46,7 +46,9 @@
static_assert((std::is_same<decltype(std::strspn(cpc, cpc)), std::size_t>::value), "");
// static_assert((std::is_same<decltype(std::strstr(cpc, cpc)), const char*>::value), "");
static_assert((std::is_same<decltype(std::strstr(cp, cpc)), char*>::value), "");
+#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
static_assert((std::is_same<decltype(std::strtok(cp, cpc)), char*>::value), "");
+#endif
static_assert((std::is_same<decltype(std::memset(vp, 0, s)), void*>::value), "");
static_assert((std::is_same<decltype(std::strerror(0)), char*>::value), "");
static_assert((std::is_same<decltype(std::strlen(cpc)), std::size_t>::value), "");
diff --git a/test/std/strings/c.strings/cwchar.pass.cpp b/test/std/strings/c.strings/cwchar.pass.cpp
index d0481b7..c3d868f 100644
--- a/test/std/strings/c.strings/cwchar.pass.cpp
+++ b/test/std/strings/c.strings/cwchar.pass.cpp
@@ -50,19 +50,13 @@
static_assert((std::is_same<decltype(std::vfwscanf(fp, L"", va)), int>::value), "");
static_assert((std::is_same<decltype(std::vswprintf(ws, s, L"", va)), int>::value), "");
static_assert((std::is_same<decltype(std::vswscanf(L"", L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vwprintf(L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::vwscanf(L"", va)), int>::value), "");
- static_assert((std::is_same<decltype(std::wprintf(L"")), int>::value), "");
- static_assert((std::is_same<decltype(std::wscanf(L"")), int>::value), "");
static_assert((std::is_same<decltype(std::fgetwc(fp)), std::wint_t>::value), "");
static_assert((std::is_same<decltype(std::fgetws(ws, 0, fp)), wchar_t*>::value), "");
static_assert((std::is_same<decltype(std::fputwc(L' ', fp)), std::wint_t>::value), "");
static_assert((std::is_same<decltype(std::fputws(L"", fp)), int>::value), "");
static_assert((std::is_same<decltype(std::fwide(fp, 0)), int>::value), "");
static_assert((std::is_same<decltype(std::getwc(fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::getwchar()), std::wint_t>::value), "");
static_assert((std::is_same<decltype(std::putwc(L' ', fp)), std::wint_t>::value), "");
- static_assert((std::is_same<decltype(std::putwchar(L' ')), std::wint_t>::value), "");
static_assert((std::is_same<decltype(std::ungetwc(L' ', fp)), std::wint_t>::value), "");
static_assert((std::is_same<decltype(std::wcstod(L"", (wchar_t**)0)), double>::value), "");
static_assert((std::is_same<decltype(std::wcstof(L"", (wchar_t**)0)), float>::value), "");
@@ -106,4 +100,16 @@
static_assert((std::is_same<decltype(std::wcrtomb(ns, L' ', &mb)), std::size_t>::value), "");
static_assert((std::is_same<decltype(std::mbsrtowcs(ws, (const char**)0, s, &mb)), std::size_t>::value), "");
static_assert((std::is_same<decltype(std::wcsrtombs(ns, (const wchar_t**)0, s, &mb)), std::size_t>::value), "");
+
+#ifndef _LIBCPP_HAS_NO_STDIN
+ static_assert((std::is_same<decltype(std::getwchar()), std::wint_t>::value), "");
+ static_assert((std::is_same<decltype(std::vwscanf(L"", va)), int>::value), "");
+ static_assert((std::is_same<decltype(std::wscanf(L"")), int>::value), "");
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+ static_assert((std::is_same<decltype(std::putwchar(L' ')), std::wint_t>::value), "");
+ static_assert((std::is_same<decltype(std::vwprintf(L"", va)), int>::value), "");
+ static_assert((std::is_same<decltype(std::wprintf(L"")), int>::value), "");
+#endif
}
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp
index c8a7425..6cfed59 100644
--- a/test/std/thread/futures/futures.async/async.pass.cpp
+++ b/test/std/thread/futures/futures.async/async.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
// <future>
diff --git a/test/std/thread/futures/futures.async/async_race.pass.cpp b/test/std/thread/futures/futures.async/async_race.pass.cpp
new file mode 100644
index 0000000..9acdd1a
--- /dev/null
+++ b/test/std/thread/futures/futures.async/async_race.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++98, c++03
+
+// <future>
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(F&& f, Args&&... args);
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(launch policy, F&& f, Args&&... args);
+
+// This test is designed to cause and allow TSAN to detect the race condition
+// reported in PR23293. (http://llvm.org/PR23293).
+
+#include <future>
+#include <chrono>
+#include <thread>
+#include <memory>
+#include <cassert>
+
+int f_async() {
+ typedef std::chrono::milliseconds ms;
+ std::this_thread::sleep_for(ms(200));
+ return 42;
+}
+
+bool ran = false;
+
+int f_deferred() {
+ ran = true;
+ return 42;
+}
+
+void test_each() {
+ {
+ std::future<int> f = std::async(f_async);
+ int const result = f.get();
+ assert(result == 42);
+ }
+ {
+ std::future<int> f = std::async(std::launch::async, f_async);
+ int const result = f.get();
+ assert(result == 42);
+ }
+ {
+ ran = false;
+ std::future<int> f = std::async(std::launch::deferred, f_deferred);
+ assert(ran == false);
+ int const result = f.get();
+ assert(ran == true);
+ assert(result == 42);
+ }
+}
+
+int main() {
+ for (int i=0; i < 25; ++i) test_each();
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
index e81adfa..e4df4ec 100644
--- a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
@@ -11,7 +11,7 @@
// class packaged_task<R(ArgTypes...)>
// template <class F, class Allocator>
-// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+// packaged_task(allocator_arg_t, const Allocator& a, F&& f);
// These constructors shall not participate in overload resolution if
// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>.
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
index 9082e57..3b49b30 100644
--- a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
@@ -22,7 +22,7 @@
{
#if _LIBCPP_STD_VER > 11
std::shared_timed_mutex m;
- m.lock();
+ m.lock_shared();
std::shared_lock<std::shared_timed_mutex> lk(m, std::adopt_lock);
assert(lk.mutex() == &m);
assert(lk.owns_lock() == true);
diff --git a/test/std/containers/sequences/dynarray/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp
similarity index 100%
copy from test/std/containers/sequences/dynarray/nothing_to_do.pass.cpp
copy to test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp
new file mode 100644
index 0000000..7bcb2d6
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex& operator=(const shared_mutex&) = delete;
+
+#include <shared_mutex>
+
+#include "test_macros.h"
+
+int main()
+{
+#if TEST_STD_VER > 14
+ std::shared_mutex m0;
+ std::shared_mutex m1;
+ m1 = m0;
+#else
+# error
+#endif
+}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
similarity index 60%
copy from test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp
copy to test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
index 7099c45..af064ae 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/no-variadics.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
@@ -7,18 +7,22 @@
//
//===----------------------------------------------------------------------===//
-// <functional>
+// <shared_mutex>
-// class function<R()>
+// class shared_mutex;
-// template<class F> function(F);
+// shared_mutex(const shared_mutex&) = delete;
-#define _LIBCPP_HAS_NO_VARIADICS
-#include <functional>
-#include <cassert>
+#include <shared_mutex>
+
+#include "test_macros.h"
int main()
{
- std::function<void()> f(static_cast<void(*)()>(0));
- assert(!f);
+#if TEST_STD_VER > 14
+ std::shared_mutex m0;
+ std::shared_mutex m1(m0);
+#else
+# error
+#endif
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
similarity index 64%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
index b58f5c5..c61a93a 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
@@ -6,7 +6,19 @@
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex();
+
+#include <shared_mutex>
int main()
{
+ std::shared_mutex m;
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
new file mode 100644
index 0000000..9bf7a79
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// void lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
new file mode 100644
index 0000000..3ffa9e2
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// void lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock_shared();
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void g()
+{
+ time_point t0 = Clock::now();
+ m.lock_shared();
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0;
+ assert(d < ms(50)); // within 50ms
+}
+
+
+int main()
+{
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ m.lock_shared();
+ for (auto& t : v)
+ t = std::thread(g);
+ std::thread q(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock_shared();
+ for (auto& t : v)
+ t.join();
+ q.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp
new file mode 100644
index 0000000..6f3ca24
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// bool try_lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp
new file mode 100644
index 0000000..5200715
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// bool try_lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock_shared());
+ assert(!m.try_lock_shared());
+ assert(!m.try_lock_shared());
+ while(!m.try_lock_shared())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+
+int main()
+{
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
index a90b6c9..45cd563 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -19,7 +20,5 @@
int main()
{
-#if _LIBCPP_STD_VER > 11
std::shared_timed_mutex m;
-#endif
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
index b4f9ba3..62bb736 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -20,8 +21,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::system_clock Clock;
@@ -40,15 +39,11 @@
assert(d < ms(50)); // within 50ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
m.lock();
std::thread t(f);
std::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
index ac5e206..8fc6299 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -21,8 +22,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::system_clock Clock;
@@ -51,11 +50,9 @@
assert(d < ms(50)); // within 50ms
}
-#endif // _LIBCPP_STD_VER > 11
int main()
{
-#if _LIBCPP_STD_VER > 11
m.lock();
std::vector<std::thread> v;
for (int i = 0; i < 5; ++i)
@@ -73,5 +70,4 @@
for (auto& t : v)
t.join();
q.join();
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
index 33b0696..61900ba 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -20,8 +21,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::system_clock Clock;
@@ -44,15 +43,11 @@
assert(d < ms(200)); // within 200ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
m.lock();
std::thread t(f);
std::this_thread::sleep_for(ms(250));
m.unlock();
t.join();
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
index 98cd8f9..ab20241 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -21,8 +22,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::steady_clock Clock;
@@ -50,11 +49,8 @@
assert(d < ms(50)); // within 50ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
{
m.lock();
std::thread t(f1);
@@ -69,5 +65,4 @@
m.unlock();
t.join();
}
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
index a006e17..9c2d8c9 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -21,8 +22,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::system_clock Clock;
@@ -45,11 +44,8 @@
assert(d < ms(200)); // within 200ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
m.lock();
std::vector<std::thread> v;
for (int i = 0; i < 5; ++i)
@@ -58,5 +54,4 @@
m.unlock();
for (auto& t : v)
t.join();
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
index b2cc15e..3544411 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -22,8 +23,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::steady_clock Clock;
@@ -51,11 +50,8 @@
assert(d < ms(50)); // within 50ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
{
m.lock();
std::vector<std::thread> v;
@@ -76,5 +72,4 @@
for (auto& t : v)
t.join();
}
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
index d1b1121..4e0f19d 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -22,8 +23,6 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
-
std::shared_timed_mutex m;
typedef std::chrono::steady_clock Clock;
@@ -51,11 +50,8 @@
assert(d < ms(50)); // within 50ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
{
m.lock();
std::vector<std::thread> v;
@@ -76,5 +72,4 @@
for (auto& t : v)
t.join();
}
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
index 5a8e624..aa90cf7 100644
--- a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
// <shared_mutex>
@@ -21,7 +22,7 @@
#include <cstdlib>
#include <cassert>
-#if _LIBCPP_STD_VER > 11
+#include "test_macros.h"
std::shared_timed_mutex m;
@@ -50,11 +51,8 @@
assert(d < ms(50)); // within 50ms
}
-#endif // _LIBCPP_STD_VER > 11
-
int main()
{
-#if _LIBCPP_STD_VER > 11
{
m.lock();
std::thread t(f1);
@@ -69,5 +67,4 @@
m.unlock();
t.join();
}
-#endif // _LIBCPP_STD_VER > 11
}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp
new file mode 100644
index 0000000..ed28809
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+#include <shared_mutex>
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+const int total_readers = 2;
+std::atomic<int> readers_started(0);
+std::atomic<int> readers_finished(0);
+
+// Wait for the readers to start then try and acquire the write lock.
+void writer_one() {
+ while (readers_started != total_readers) {}
+ bool b = m.try_lock_for(std::chrono::milliseconds(500));
+ assert(b == false);
+}
+
+void blocked_reader() {
+ ++readers_started;
+ // Wait until writer_one is waiting for the write lock.
+ while (m.try_lock_shared()) {
+ m.unlock_shared();
+ }
+ // Attempt to get the read lock. writer_one should be blocking us because
+ // writer_one is blocked by main.
+ m.lock_shared();
+ ++readers_finished;
+ m.unlock_shared();
+}
+
+int main()
+{
+ typedef std::chrono::steady_clock Clock;
+
+ m.lock_shared();
+ std::thread t1(writer_one);
+ // create some readers
+ std::thread t2(blocked_reader);
+ std::thread t3(blocked_reader);
+ // Kill the test after 10 seconds if it hasn't completed.
+ auto end_point = Clock::now() + std::chrono::seconds(10);
+ while (readers_finished != total_readers && Clock::now() < end_point) {
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ }
+ assert(readers_finished == total_readers);
+ m.unlock_shared();
+ t1.join();
+ t2.join();
+ t3.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
index 5395c85..89b9934 100644
--- a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
+++ b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
@@ -14,7 +14,7 @@
// struct once_flag;
// template<class Callable, class ...Args>
-// void call_once(once_flag& flag, Callable func, Args&&... args);
+// void call_once(once_flag& flag, Callable&& func, Args&&... args);
#include <mutex>
#include <thread>
@@ -153,6 +153,35 @@
}
};
+class NonCopyable
+{
+#if !defined(__clang__)
+ // GCC 4.8 complains about the following being private
+public:
+ NonCopyable(const NonCopyable&)
+ {
+ }
+#else
+ NonCopyable(const NonCopyable&);
+#endif
+public:
+ NonCopyable() {}
+
+ void operator()(int&) {}
+};
+
+#if __cplusplus >= 201103L
+// reference qualifiers on functions are a C++11 extension
+struct RefQual
+{
+ int lv_called, rv_called;
+
+ RefQual() : lv_called(0), rv_called(0) {}
+
+ void operator()() & { ++lv_called; }
+ void operator()() && { ++rv_called; }
+};
+#endif
#endif
int main()
@@ -204,5 +233,22 @@
std::once_flag f;
std::call_once(f, MoveOnly(), MoveOnly());
}
+ // check LWG2442: call_once() shouldn't DECAY_COPY()
+ {
+ std::once_flag f;
+ int i = 0;
+ std::call_once(f, NonCopyable(), i);
+ }
+#if __cplusplus >= 201103L
+// reference qualifiers on functions are a C++11 extension
+ {
+ std::once_flag f1, f2;
+ RefQual rq;
+ std::call_once(f1, rq);
+ assert(rq.lv_called == 1);
+ std::call_once(f2, std::move(rq));
+ assert(rq.rv_called == 1);
+ }
+#endif
#endif // _LIBCPP_HAS_NO_VARIADICS
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
index 476ca0c..4d3a742 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
@@ -45,7 +45,8 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
std::thread::id id0 = t0.get_id();
std::thread t1;
std::thread::id id1 = t1.get_id();
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
index 94a30e7..2db9430 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
@@ -48,13 +48,16 @@
{
assert(G::n_alive == 0);
assert(!G::op_run);
- std::thread t0(G(), 5, 5.5);
+ {
+ G g;
+ std::thread t0(g, 5, 5.5);
std::thread::id id = t0.get_id();
std::thread t1;
t1 = std::move(t0);
assert(t1.get_id() == id);
assert(t0.get_id() == std::thread::id());
t1.join();
+ }
assert(G::n_alive == 0);
assert(G::op_run);
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
index 8cb2cb1..6c31df5 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
@@ -8,10 +8,7 @@
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads
-
-// NOTE: std::terminate is called so the destructors are not invoked and the
-// memory is not freed. This will cause ASAN to fail.
-// XFAIL: asan
+// UNSUPPORTED: c++98, c++03
// <thread>
@@ -35,12 +32,7 @@
G(const G& g) : alive_(g.alive_) {++n_alive;}
~G() {alive_ = 0; --n_alive;}
- void operator()()
- {
- assert(alive_ == 1);
- assert(n_alive >= 1);
- op_run = true;
- }
+
void operator()(int i, double j)
{
@@ -57,19 +49,18 @@
void f1()
{
- std::exit(0);
+ std::_Exit(0);
}
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
std::set_terminate(f1);
{
- std::thread t0(G(), 5, 5.5);
+ G g;
+ std::thread t0(g, 5, 5.5);
std::thread::id id = t0.get_id();
std::thread t1;
t0 = std::move(t1);
assert(false);
}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
index 0f5d5aa..a8b4be1 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
@@ -15,7 +15,7 @@
// template <class F, class ...Args> thread(F&& f, Args&&... args);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <thread>
#include <new>
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
index 36e0fbd..e88304e 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
@@ -55,16 +55,18 @@
{
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{
- assert(G::n_alive == 0);
+ G g;
+ assert(G::n_alive == 1);
assert(!G::op_run);
- std::thread t0(G(), 5, 5.5);
+ std::thread t0(g, 5, 5.5);
std::thread::id id = t0.get_id();
std::thread t1 = std::move(t0);
assert(t1.get_id() == id);
assert(t0.get_id() == std::thread::id());
t1.join();
- assert(G::n_alive == 0);
+ assert(G::n_alive == 1);
assert(G::op_run);
}
+ assert(G::n_alive == 0);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
index 20c8da1..ddf96d0 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
@@ -9,6 +9,9 @@
//
// UNSUPPORTED: libcpp-has-no-threads
+// NOTE: TSAN will report this test as leaking a thread.
+// XFAIL: tsan
+
// <thread>
// class thread
@@ -53,8 +56,11 @@
{
assert(G::n_alive == 0);
assert(!G::op_run);
- std::thread t((G()));
- std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ G g;
+ {
+ std::thread t(g);
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
}
assert(false);
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
index 5a31232..f4a4d1f 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
@@ -16,26 +16,41 @@
// void detach();
#include <thread>
-#include <new>
-#include <cstdlib>
+#include <atomic>
#include <cassert>
+std::atomic_bool done = ATOMIC_VAR_INIT(false);
+
class G
{
int alive_;
+ bool done_;
public:
static int n_alive;
static bool op_run;
- G() : alive_(1) {++n_alive;}
- G(const G& g) : alive_(g.alive_) {++n_alive;}
- ~G() {alive_ = 0; --n_alive;}
+ G() : alive_(1), done_(false)
+ {
+ ++n_alive;
+ }
+
+ G(const G& g) : alive_(g.alive_), done_(false)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ if (done_) done = true;
+ }
void operator()()
{
assert(alive_ == 1);
assert(n_alive >= 1);
op_run = true;
+ done_ = true;
}
};
@@ -45,12 +60,14 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
assert(t0.joinable());
t0.detach();
assert(!t0.joinable());
- std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ while (!done) {}
assert(G::op_run);
- assert(G::n_alive == 0);
+ assert(G::n_alive == 1);
}
+ assert(G::n_alive == 0);
}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
index a5ea55a..5cca7b0 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
@@ -45,7 +45,8 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
std::thread::id id0 = t0.get_id();
std::thread t1;
std::thread::id id1 = t1.get_id();
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
index 2559303..0512e49 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
@@ -45,7 +45,8 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
assert(t0.joinable());
t0.join();
assert(!t0.joinable());
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
index 351c1cf..b97839c 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
@@ -45,7 +45,8 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
assert(t0.joinable());
t0.join();
assert(!t0.joinable());
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
index 37c2d9c..c8807a9 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
@@ -45,7 +45,8 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
pthread_t pid = t0.native_handle();
assert(pid != 0);
t0.join();
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
index e8dede1..49d4618 100644
--- a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
@@ -45,7 +45,8 @@
int main()
{
{
- std::thread t0((G()));
+ G g;
+ std::thread t0(g);
std::thread::id id0 = t0.get_id();
std::thread t1;
std::thread::id id1 = t1.get_id();
diff --git a/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
index bffb5f3..27e1d2a 100644
--- a/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
+++ b/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
@@ -17,14 +17,17 @@
#include <thread>
#include <cstdlib>
#include <cassert>
+#include <cstring>
#include <signal.h>
#include <sys/time.h>
+void sig_action(int) {}
+
int main()
{
int ec;
struct sigaction action;
- action.sa_handler = [](int) {};
+ action.sa_handler = &sig_action;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
@@ -32,7 +35,7 @@
assert(!ec);
struct itimerval it;
- it.it_interval = { 0 };
+ std::memset(&it, 0, sizeof(itimerval));
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 250000;
// This will result in a SIGALRM getting fired resulting in the nanosleep
diff --git a/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp
new file mode 100644
index 0000000..e19e731
--- /dev/null
+++ b/test/std/utilities/allocator.adaptor/allocator.adaptor.types/is_always_equal.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class OuterAlloc, class... InnerAllocs>
+// class scoped_allocator_adaptor
+
+// typedef see below is_always_equal;
+
+#include <scoped_allocator>
+#include <type_traits>
+
+#include "allocators.h"
+#include "min_allocator.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+ // sanity checks
+ static_assert( (std::is_same<
+ std::allocator_traits<A1<int>>::is_always_equal, std::false_type>::value
+ ), "" );
+
+ static_assert( (std::is_same<
+ std::allocator_traits<min_allocator<int>>::is_always_equal, std::true_type>::value
+ ), "" );
+
+ // wrapping one allocator
+ static_assert(
+ (std::is_same<
+ std::scoped_allocator_adaptor<A1<int>>::is_always_equal,
+ std::allocator_traits<A1<int>>::is_always_equal
+ >::value), "");
+
+ // wrapping one allocator
+ static_assert(
+ (std::is_same<
+ std::scoped_allocator_adaptor<min_allocator<int>>::is_always_equal,
+ std::allocator_traits<min_allocator<int>>::is_always_equal
+ >::value), "");
+
+ // wrapping two allocators (check the values instead of the types)
+ static_assert((
+ std::scoped_allocator_adaptor<A1<int>, A2<int>>::is_always_equal::value ==
+ ( std::allocator_traits<A1<int>>::is_always_equal::value &&
+ std::allocator_traits<A2<int>>::is_always_equal::value)
+ ), "");
+
+ // wrapping two allocators (check the values instead of the types)
+ static_assert((
+ std::scoped_allocator_adaptor<A1<int>, min_allocator<int>>::is_always_equal::value ==
+ ( std::allocator_traits<A1<int>>::is_always_equal::value &&
+ std::allocator_traits<min_allocator<int>>::is_always_equal::value)
+ ), "");
+
+
+ // wrapping three allocators (check the values instead of the types)
+ static_assert((
+ std::scoped_allocator_adaptor<A1<int>, A2<int>, A3<int>>::is_always_equal::value ==
+ ( std::allocator_traits<A1<int>>::is_always_equal::value &&
+ std::allocator_traits<A2<int>>::is_always_equal::value &&
+ std::allocator_traits<A3<int>>::is_always_equal::value)
+ ), "");
+
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp
similarity index 67%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp
index b58f5c5..3a9749e 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/utilities/date.time/asctime.thread-unsafe.fail.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // asctime is not thread-safe.
+ std::time_t t = 0;
+ std::asctime(&t);
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp
similarity index 68%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp
index b58f5c5..cd246c6 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/utilities/date.time/ctime.thread-unsafe.fail.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // ctime is not thread-safe.
+ std::time_t t = 0;
+ std::ctime(&t);
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp
similarity index 68%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp
index b58f5c5..a6debcb 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/utilities/date.time/gmtime.thread-unsafe.fail.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // gmtime is not thread-safe.
+ std::time_t t = 0;
+ std::gmtime(&t);
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp
similarity index 67%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp
index b58f5c5..c9e55c8 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/utilities/date.time/localtime.thread-unsafe.fail.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
+// REQUIRES: libcpp-has-no-thread-unsafe-c-functions
+
+#include <ctime>
+
+int main() {
+ // localtime is not thread-safe.
+ std::time_t t = 0;
+ std::localtime(&t);
}
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp
index 6315598..ad03e8f 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
index 33bf018..4577d0b 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp
index ab4dd59..815096f 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_int_0.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp
index af5efe4..f69afbf 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_lvalue.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp
index 4913a51..a1137ee 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_rvalue.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp
index 03447db..73f26e4 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_void_0.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
@@ -39,21 +41,34 @@
void f() {++count;}
-struct A_int_0
+int g() {++count; return 0;}
+
+struct A_void_0
{
void operator()() {++count;}
void operator()() const {count += 2;}
};
+struct A_int_0
+{
+ int operator()() {++count; return 4;}
+ int operator()() const {count += 2; return 5;}
+};
+
int main()
{
test(std::bind(f));
test(std::bind(&f));
- test(std::bind(A_int_0()));
- test_const(std::bind(A_int_0()));
+ test(std::bind(A_void_0()));
+ test_const(std::bind(A_void_0()));
test(std::bind<void>(f));
test(std::bind<void>(&f));
+ test(std::bind<void>(A_void_0()));
+ test_const(std::bind<void>(A_void_0()));
+
+ test(std::bind<void>(g));
+ test(std::bind<void>(&g));
test(std::bind<void>(A_int_0()));
test_const(std::bind<void>(A_int_0()));
}
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
index 12720f7..f61d93a 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/nested.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<CopyConstructible Fn, CopyConstructible... Types>
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp
index 7f8dd4a..83fa452 100644
--- a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression.pass.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++98, c++03
+
// <functional>
// template<class T> struct is_bind_expression
diff --git a/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression_03.pass.cpp b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression_03.pass.cpp
new file mode 100644
index 0000000..12a78db
--- /dev/null
+++ b/test/std/utilities/function.objects/bind/func.bind/func.bind.isbind/is_bind_expression_03.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+//-----------------------------------------------------------------------------
+// TESTING template<class T> struct is_bind_expression
+//
+// bind is not implemented in C++03 so nothing is a bind expression. However
+// for compatibility reasons the trait is_bind_expression should be available
+// in C++03 and it should always return false.
+
+#include <functional>
+
+template <class T>
+void test() {
+ static_assert(!std::is_bind_expression<T>::value, "");
+}
+
+struct C {};
+
+int main() {
+ test<int>();
+ test<void>();
+ test<C>();
+ test<C&>();
+ test<C const&>();
+ test<C*>();
+ test<void()>();
+ test<int(*)()>();
+ test<int (C::*)()>();
+ test<decltype(std::placeholders::_2)>();
+}
diff --git a/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp
new file mode 100644
index 0000000..4b9cc76
--- /dev/null
+++ b/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp
@@ -0,0 +1,268 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// <functional>
+
+// template <class F, class ...Args>
+// result_of_t<F&&(Args&&...)> invoke(F&&, Args&&...);
+
+/// C++14 [func.def] 20.9.0
+/// (1) The following definitions apply to this Clause:
+/// (2) A call signature is the name of a return type followed by a parenthesized
+/// comma-separated list of zero or more argument types.
+/// (3) A callable type is a function object type (20.9) or a pointer to member.
+/// (4) A callable object is an object of a callable type.
+/// (5) A call wrapper type is a type that holds a callable object and supports
+/// a call operation that forwards to that object.
+/// (6) A call wrapper is an object of a call wrapper type.
+/// (7) A target object is the callable object held by a call wrapper.
+
+/// C++14 [func.require] 20.9.1
+///
+/// Define INVOKE (f, t1, t2, ..., tN) as follows:
+/// (1.1) - (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of
+/// type T or a reference to an object of type T or a reference to an object of a type derived from T;
+/// (1.2) - ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of
+/// the types described in the previous item;
+/// (1.3) - t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a
+/// reference to an object of type T or a reference to an object of a type derived from T;
+/// (1.4) - (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types
+/// described in the previous item;
+/// (1.5) - f(t1, t2, ..., tN) in all other cases.
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+struct NonCopyable {
+ NonCopyable() {}
+private:
+ NonCopyable(NonCopyable const&) = delete;
+ NonCopyable& operator=(NonCopyable const&) = delete;
+};
+
+struct TestClass {
+ explicit TestClass(int x) : data(x) {}
+
+ int& operator()(NonCopyable&&) & { return data; }
+ int const& operator()(NonCopyable&&) const & { return data; }
+ int volatile& operator()(NonCopyable&&) volatile & { return data; }
+ int const volatile& operator()(NonCopyable&&) const volatile & { return data; }
+
+ int&& operator()(NonCopyable&&) && { return std::move(data); }
+ int const&& operator()(NonCopyable&&) const && { return std::move(data); }
+ int volatile&& operator()(NonCopyable&&) volatile && { return std::move(data); }
+ int const volatile&& operator()(NonCopyable&&) const volatile && { return std::move(data); }
+
+ int data;
+private:
+ TestClass(TestClass const&) = delete;
+ TestClass& operator=(TestClass const&) = delete;
+};
+
+struct DerivedFromTestClass : public TestClass {
+ explicit DerivedFromTestClass(int x) : TestClass(x) {}
+};
+
+int& foo(NonCopyable&&) {
+ static int data = 42;
+ return data;
+}
+
+template <class Signature, class Expect, class Functor>
+void test_b12(Functor&& f) {
+ // Create the callable object.
+ typedef Signature TestClass::*ClassFunc;
+ ClassFunc func_ptr = &TestClass::operator();
+
+ // Create the dummy arg.
+ NonCopyable arg;
+
+ // Check that the deduced return type of invoke is what is expected.
+ typedef decltype(
+ std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg))
+ ) DeducedReturnType;
+ static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
+
+ // Check that result_of_t matches Expect.
+ typedef typename std::result_of<ClassFunc&&(Functor&&, NonCopyable&&)>::type
+ ResultOfReturnType;
+ static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
+
+ // Run invoke and check the return value.
+ DeducedReturnType ret =
+ std::invoke(func_ptr, std::forward<Functor>(f), std::move(arg));
+ assert(ret == 42);
+}
+
+template <class Expect, class Functor>
+void test_b34(Functor&& f) {
+ // Create the callable object.
+ typedef int TestClass::*ClassFunc;
+ ClassFunc func_ptr = &TestClass::data;
+
+ // Check that the deduced return type of invoke is what is expected.
+ typedef decltype(
+ std::invoke(func_ptr, std::forward<Functor>(f))
+ ) DeducedReturnType;
+ static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
+
+ // Check that result_of_t matches Expect.
+ typedef typename std::result_of<ClassFunc&&(Functor&&)>::type
+ ResultOfReturnType;
+ static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
+
+ // Run invoke and check the return value.
+ DeducedReturnType ret =
+ std::invoke(func_ptr, std::forward<Functor>(f));
+ assert(ret == 42);
+}
+
+template <class Expect, class Functor>
+void test_b5(Functor&& f) {
+ NonCopyable arg;
+
+ // Check that the deduced return type of invoke is what is expected.
+ typedef decltype(
+ std::invoke(std::forward<Functor>(f), std::move(arg))
+ ) DeducedReturnType;
+ static_assert((std::is_same<DeducedReturnType, Expect>::value), "");
+
+ // Check that result_of_t matches Expect.
+ typedef typename std::result_of<Functor&&(NonCopyable&&)>::type
+ ResultOfReturnType;
+ static_assert((std::is_same<ResultOfReturnType, Expect>::value), "");
+
+ // Run invoke and check the return value.
+ DeducedReturnType ret = std::invoke(std::forward<Functor>(f), std::move(arg));
+ assert(ret == 42);
+}
+
+void bullet_one_two_tests() {
+ {
+ TestClass cl(42);
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+
+ test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
+ test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
+ test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
+ test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
+ }
+ {
+ DerivedFromTestClass cl(42);
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+
+ test_b12<int&&(NonCopyable&&) &&, int&&>(std::move(cl));
+ test_b12<int const&&(NonCopyable&&) const &&, int const&&>(std::move(cl));
+ test_b12<int volatile&&(NonCopyable&&) volatile &&, int volatile&&>(std::move(cl));
+ test_b12<int const volatile&&(NonCopyable&&) const volatile &&, int const volatile&&>(std::move(cl));
+ }
+ {
+ TestClass cl_obj(42);
+ TestClass *cl = &cl_obj;
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+ }
+ {
+ DerivedFromTestClass cl_obj(42);
+ DerivedFromTestClass *cl = &cl_obj;
+ test_b12<int&(NonCopyable&&) &, int&>(cl);
+ test_b12<int const&(NonCopyable&&) const &, int const&>(cl);
+ test_b12<int volatile&(NonCopyable&&) volatile &, int volatile&>(cl);
+ test_b12<int const volatile&(NonCopyable&&) const volatile &, int const volatile&>(cl);
+ }
+}
+
+void bullet_three_four_tests() {
+ {
+ typedef TestClass Fn;
+ Fn cl(42);
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const&>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
+
+ test_b34<int&&>(static_cast<Fn &&>(cl));
+ test_b34<int const&&>(static_cast<Fn const&&>(cl));
+ test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
+ test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
+ }
+ {
+ typedef DerivedFromTestClass Fn;
+ Fn cl(42);
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const&>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile&>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile &>(cl));
+
+ test_b34<int&&>(static_cast<Fn &&>(cl));
+ test_b34<int const&&>(static_cast<Fn const&&>(cl));
+ test_b34<int volatile&&>(static_cast<Fn volatile&&>(cl));
+ test_b34<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
+ }
+ {
+ typedef TestClass Fn;
+ Fn cl_obj(42);
+ Fn* cl = &cl_obj;
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const*>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
+ }
+ {
+ typedef DerivedFromTestClass Fn;
+ Fn cl_obj(42);
+ Fn* cl = &cl_obj;
+ test_b34<int&>(cl);
+ test_b34<int const&>(static_cast<Fn const*>(cl));
+ test_b34<int volatile&>(static_cast<Fn volatile*>(cl));
+ test_b34<int const volatile&>(static_cast<Fn const volatile *>(cl));
+ }
+}
+
+void bullet_five_tests() {
+ using FooType = int&(NonCopyable&&);
+ {
+ FooType& fn = foo;
+ test_b5<int &>(fn);
+ }
+ {
+ FooType* fn = foo;
+ test_b5<int &>(fn);
+ }
+ {
+ typedef TestClass Fn;
+ Fn cl(42);
+ test_b5<int&>(cl);
+ test_b5<int const&>(static_cast<Fn const&>(cl));
+ test_b5<int volatile&>(static_cast<Fn volatile&>(cl));
+ test_b5<int const volatile&>(static_cast<Fn const volatile &>(cl));
+
+ test_b5<int&&>(static_cast<Fn &&>(cl));
+ test_b5<int const&&>(static_cast<Fn const&&>(cl));
+ test_b5<int volatile&&>(static_cast<Fn volatile&&>(cl));
+ test_b5<int const volatile&&>(static_cast<Fn const volatile&&>(cl));
+ }
+}
+
+int main() {
+ bullet_one_two_tests();
+ bullet_three_four_tests();
+ bullet_five_tests();
+}
diff --git a/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp b/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp
new file mode 100644
index 0000000..e579f20
--- /dev/null
+++ b/test/std/utilities/function.objects/func.require/bullet_1_and_2.pass.cpp
@@ -0,0 +1,318 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// INVOKE (f, t1, t2, ..., tN)
+
+//------------------------------------------------------------------------------
+// TESTING INVOKE(f, t1, t2, ..., tN)
+// - Bullet 1 -- (t1.*f)(t2, ..., tN)
+// - Bullet 2 -- ((*t1).*f)(t2, ..., tN)
+//
+// Overview:
+// Bullets 1 and 2 handle the case where 'f' is a pointer to member function.
+// Bullet 1 only handles the cases where t1 is an object of type T or a
+// type derived from 'T'. Bullet 2 handles all other cases.
+//
+// Concerns:
+// 1) cv-qualified member function signatures are accepted.
+// 2) reference qualified member function signatures are accepted.
+// 3) member functions with varargs at the end are accepted.
+// 4) The arguments are perfect forwarded to the member function call.
+// 5) Classes that are publicly derived from 'T' are accepted as the call object
+// 6) All types that dereference to T or a type derived from T can be used
+// as the call object.
+// 7) Pointers to T or a type derived from T can be used as the call object.
+// 8) Reference return types are properly deduced.
+//
+//
+// Plan:
+// 1) Create a class that contains a set, 'S', of non-static functions.
+// 'S' should include functions that cover every single combination
+// of qualifiers and varargs for arities of 0, 1 and 2 (C-1,2,3).
+// The argument types used in the functions should be non-copyable (C-4).
+// The functions should return 'MethodID::setUncheckedCall()'.
+//
+// 2) Create a set of supported call object, 'Objs', of different types
+// and behaviors. (C-5,6,7)
+//
+// 3) Attempt to call each function, 'f', in 'S' with each call object, 'c',
+// in 'Objs'. After every attempted call to 'f' check that 'f' was
+// actually called using 'MethodID::checkCalled(<return-value>)'
+//
+// 3b) If 'f' is reference qualified call 'f' with the properly qualified
+// call object. Otherwise call 'f' with lvalue call objects.
+//
+// 3a) If 'f' is const, volatile, or cv qualified then call it with call
+// objects that are equally or less cv-qualified.
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "invoke_helpers.h"
+
+//==============================================================================
+// MemFun03 - C++03 compatible set of test member functions.
+struct MemFun03 {
+ typedef void*& R;
+#define F(...) \
+ R f(__VA_ARGS__) { return MethodID<R(MemFun03::*)(__VA_ARGS__)>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const { return MethodID<R(MemFun03::*)(__VA_ARGS__) const>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) volatile>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const volatile { return MethodID<R(MemFun03::*)(__VA_ARGS__) const volatile>::setUncheckedCall(); }
+#
+ F()
+ F(...)
+ F(ArgType&)
+ F(ArgType&, ...)
+ F(ArgType&, ArgType&)
+ F(ArgType&, ArgType&, ...)
+ F(ArgType&, ArgType&, ArgType&)
+ F(ArgType&, ArgType&, ArgType&, ...)
+#undef F
+public:
+ MemFun03() {}
+private:
+ MemFun03(MemFun03 const&);
+ MemFun03& operator=(MemFun03 const&);
+};
+
+
+#if TEST_STD_VER >= 11
+
+//==============================================================================
+// MemFun11 - C++11 reference qualified test member functions.
+struct MemFun11 {
+ typedef void*& R;
+ typedef MemFun11 C;
+#define F(...) \
+ R f(__VA_ARGS__) & { return MethodID<R(C::*)(__VA_ARGS__) &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const & { return MethodID<R(C::*)(__VA_ARGS__) const &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) volatile & { return MethodID<R(C::*)(__VA_ARGS__) volatile &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const volatile & { return MethodID<R(C::*)(__VA_ARGS__) const volatile &>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) && { return MethodID<R(C::*)(__VA_ARGS__) &&>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const && { return MethodID<R(C::*)(__VA_ARGS__) const &&>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) volatile && { return MethodID<R(C::*)(__VA_ARGS__) volatile &&>::setUncheckedCall(); } \
+ R f(__VA_ARGS__) const volatile && { return MethodID<R(C::*)(__VA_ARGS__) const volatile &&>::setUncheckedCall(); }
+#
+ F()
+ F(...)
+ F(ArgType&&)
+ F(ArgType&&, ...)
+ F(ArgType&&, ArgType&&)
+ F(ArgType&&, ArgType&&, ...)
+ F(ArgType&&, ArgType&&, ArgType&&)
+ F(ArgType&&, ArgType&&, ArgType&&, ...)
+#undef F
+public:
+ MemFun11() {}
+private:
+ MemFun11(MemFun11 const&);
+ MemFun11& operator=(MemFun11 const&);
+};
+
+#endif // TEST_STD_VER >= 11
+
+
+//==============================================================================
+// TestCase - A test case for a single member function.
+// ClassType - The type of the class being tested.
+// CallSig - The function signature of the method being tested.
+// Arity - the arity of 'CallSig'
+// CV - the cv qualifiers of 'CallSig' represented as a type tag.
+// RValue - The method is RValue qualified.
+// ArgRValue - Call the method with RValue arguments.
+template <class ClassType, class CallSig, int Arity, class CV,
+ bool RValue = false, bool ArgRValue = false>
+struct TestCaseImp {
+public:
+
+ static void run() { TestCaseImp().doTest(); }
+
+private:
+ //==========================================================================
+ // TEST DISPATCH
+ void doTest() {
+ // (Plan-2) Create test call objects.
+ typedef ClassType T;
+ typedef DerivedFromType<T> D;
+ T obj;
+ T* obj_ptr = &obj;
+ D der;
+ D* der_ptr = &der;
+ DerefToType<T> dref;
+ DerefPropType<T> dref2;
+
+ // (Plan-3) Dispatch based on the CV tags.
+ CV tag;
+ Bool<!RValue> NotRValue;
+ runTestDispatch(tag, obj);
+ runTestDispatch(tag, der);
+ runTestDispatch(tag, dref2);
+ runTestDispatchIf(NotRValue, tag, dref);
+ runTestDispatchIf(NotRValue, tag, obj_ptr);
+ runTestDispatchIf(NotRValue, tag, der_ptr);
+ }
+
+ template <class QT, class Tp>
+ void runTestDispatchIf(Bool<true>, QT q, Tp& v) {
+ runTestDispatch(q, v);
+ }
+
+ template <class QT, class Tp>
+ void runTestDispatchIf(Bool<false>, QT, Tp&) {
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_None, Tp& v) {
+ runTest(v);
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_Const, Tp& v) {
+ Tp const& cv = v;
+ runTest(v);
+ runTest(cv);
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_Volatile, Tp& v) {
+ Tp volatile& vv = v;
+ runTest(v);
+ runTest(vv);
+ }
+
+ template <class Tp>
+ void runTestDispatch(Q_CV, Tp& v) {
+ Tp const& cv = v;
+ Tp volatile& vv = v;
+ Tp const volatile& cvv = v;
+ runTest(v);
+ runTest(cv);
+ runTest(vv);
+ runTest(cvv);
+ }
+
+ template <class Obj>
+ void runTest(Obj& obj) {
+ typedef Caster<Q_None, RValue> SCast;
+ typedef Caster<Q_None, ArgRValue> ACast;
+ typedef CallSig (ClassType::*MemPtr);
+ // Delegate test to logic in invoke_helpers.h
+ BasicTest<MethodID<MemPtr>, Arity, SCast, ACast> b;
+ b.runTest( (MemPtr)&ClassType::f, obj);
+ }
+};
+
+template <class Sig, int Arity, class CV>
+struct TestCase : public TestCaseImp<MemFun03, Sig, Arity, CV> {};
+
+#if TEST_STD_VER >= 11
+template <class Sig, int Arity, class CV, bool RValue = false>
+struct TestCase11 : public TestCaseImp<MemFun11, Sig, Arity, CV, RValue, true> {};
+#endif
+
+int main() {
+ typedef void*& R;
+ typedef ArgType A;
+ TestCase<R(), 0, Q_None>::run();
+ TestCase<R() const, 0, Q_Const>::run();
+ TestCase<R() volatile, 0, Q_Volatile>::run();
+ TestCase<R() const volatile, 0, Q_CV>::run();
+ TestCase<R(...), 0, Q_None>::run();
+ TestCase<R(...) const, 0, Q_Const>::run();
+ TestCase<R(...) volatile, 0, Q_Volatile>::run();
+ TestCase<R(...) const volatile, 0, Q_CV>::run();
+ TestCase<R(A&), 1, Q_None>::run();
+ TestCase<R(A&) const, 1, Q_Const>::run();
+ TestCase<R(A&) volatile, 1, Q_Volatile>::run();
+ TestCase<R(A&) const volatile, 1, Q_CV>::run();
+ TestCase<R(A&, ...), 1, Q_None>::run();
+ TestCase<R(A&, ...) const, 1, Q_Const>::run();
+ TestCase<R(A&, ...) volatile, 1, Q_Volatile>::run();
+ TestCase<R(A&, ...) const volatile, 1, Q_CV>::run();
+ TestCase<R(A&, A&), 2, Q_None>::run();
+ TestCase<R(A&, A&) const, 2, Q_Const>::run();
+ TestCase<R(A&, A&) volatile, 2, Q_Volatile>::run();
+ TestCase<R(A&, A&) const volatile, 2, Q_CV>::run();
+ TestCase<R(A&, A&, ...), 2, Q_None>::run();
+ TestCase<R(A&, A&, ...) const, 2, Q_Const>::run();
+ TestCase<R(A&, A&, ...) volatile, 2, Q_Volatile>::run();
+ TestCase<R(A&, A&, ...) const volatile, 2, Q_CV>::run();
+ TestCase<R(A&, A&, A&), 3, Q_None>::run();
+ TestCase<R(A&, A&, A&) const, 3, Q_Const>::run();
+ TestCase<R(A&, A&, A&) volatile, 3, Q_Volatile>::run();
+ TestCase<R(A&, A&, A&) const volatile, 3, Q_CV>::run();
+ TestCase<R(A&, A&, A&, ...), 3, Q_None>::run();
+ TestCase<R(A&, A&, A&, ...) const, 3, Q_Const>::run();
+ TestCase<R(A&, A&, A&, ...) volatile, 3, Q_Volatile>::run();
+ TestCase<R(A&, A&, A&, ...) const volatile, 3, Q_CV>::run();
+
+#if TEST_STD_VER >= 11
+ TestCase11<R() &, 0, Q_None>::run();
+ TestCase11<R() const &, 0, Q_Const>::run();
+ TestCase11<R() volatile &, 0, Q_Volatile>::run();
+ TestCase11<R() const volatile &, 0, Q_CV>::run();
+ TestCase11<R(...) &, 0, Q_None>::run();
+ TestCase11<R(...) const &, 0, Q_Const>::run();
+ TestCase11<R(...) volatile &, 0, Q_Volatile>::run();
+ TestCase11<R(...) const volatile &, 0, Q_CV>::run();
+ TestCase11<R(A&&) &, 1, Q_None>::run();
+ TestCase11<R(A&&) const &, 1, Q_Const>::run();
+ TestCase11<R(A&&) volatile &, 1, Q_Volatile>::run();
+ TestCase11<R(A&&) const volatile &, 1, Q_CV>::run();
+ TestCase11<R(A&&, ...) &, 1, Q_None>::run();
+ TestCase11<R(A&&, ...) const &, 1, Q_Const>::run();
+ TestCase11<R(A&&, ...) volatile &, 1, Q_Volatile>::run();
+ TestCase11<R(A&&, ...) const volatile &, 1, Q_CV>::run();
+ TestCase11<R(A&&, A&&) &, 2, Q_None>::run();
+ TestCase11<R(A&&, A&&) const &, 2, Q_Const>::run();
+ TestCase11<R(A&&, A&&) volatile &, 2, Q_Volatile>::run();
+ TestCase11<R(A&&, A&&) const volatile &, 2, Q_CV>::run();
+ TestCase11<R(A&&, A&&, ...) &, 2, Q_None>::run();
+ TestCase11<R(A&&, A&&, ...) const &, 2, Q_Const>::run();
+ TestCase11<R(A&&, A&&, ...) volatile &, 2, Q_Volatile>::run();
+ TestCase11<R(A&&, A&&, ...) const volatile &, 2, Q_CV>::run();
+ TestCase11<R() &&, 0, Q_None, /* RValue */ true>::run();
+ TestCase11<R() const &&, 0, Q_Const, /* RValue */ true>::run();
+ TestCase11<R() volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R() const volatile &&, 0, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(...) &&, 0, Q_None, /* RValue */ true>::run();
+ TestCase11<R(...) const &&, 0, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(...) volatile &&, 0, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(...) const volatile &&, 0, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&) &&, 1, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&) const &&, 1, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) &&, 1, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) const &&, 1, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) volatile &&, 1, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, ...) const volatile &&, 1, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) &&, 2, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) const &&, 2, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) &&, 2, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) const &&, 2, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) volatile &&, 2, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, ...) const volatile &&, 2, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) &&, 3, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) const &&, 3, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) &&, 3, Q_None, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) const &&, 3, Q_Const, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) volatile &&, 3, Q_Volatile, /* RValue */ true>::run();
+ TestCase11<R(A&&, A&&, A&&, ...) const volatile &&, 3, Q_CV, /* RValue */ true>::run();
+#endif
+}
\ No newline at end of file
diff --git a/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp b/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp
new file mode 100644
index 0000000..b6fe190
--- /dev/null
+++ b/test/std/utilities/function.objects/func.require/bullet_3_and_4.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// INVOKE (f, t1, t2, ..., tN)
+
+//------------------------------------------------------------------------------
+// TESTING INVOKE(f, t1, t2, ..., tN)
+// - Bullet 3 -- t1.*f
+// - Bullet 4 -- (*t1).*f
+//
+// Overview:
+// Bullets 3 and 4 handle the case where 'f' is a pointer to member object.
+// Bullet 3 only handles the cases where t1 is an object of type T or a
+// type derived from 'T'. Bullet 4 handles all other cases.
+//
+// Concerns:
+// 1) The return type is always an lvalue reference.
+// 2) The return type is not less cv-qualified that the object that contains it.
+// 3) The return type is not less cv-qualified than object type.
+// 4) The call object is perfectly forwarded.
+// 5) Classes that are publicly derived from 'T' are accepted as the call object
+// 6) All types that dereference to T or a type derived from T can be used
+// as the call object.
+// 7) Pointers to T or a type derived from T can be used as the call object.
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "invoke_helpers.h"
+
+template <class Tp>
+struct TestMemberObject {
+ TestMemberObject() : object() {}
+ Tp object;
+private:
+ TestMemberObject(TestMemberObject const&);
+ TestMemberObject& operator=(TestMemberObject const&);
+};
+
+template <class ObjectType>
+struct TestCase {
+ public:
+
+ static void run() { TestCase().doTest(); }
+
+private:
+ typedef TestMemberObject<ObjectType> TestType;
+
+ //==========================================================================
+ // TEST DISPATCH
+ void doTest() {
+ typedef DerivedFromType<TestType> Derived;
+ TestType obj;
+ TestType* obj_ptr = &obj;
+ Derived der;
+ Derived* der_ptr = &der;
+ DerefToType<TestType> dref;
+ DerefPropType<TestType> dref2;
+
+ {
+ typedef ObjectType (TestType::*MemPtr);
+ typedef ObjectType E;
+ MemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
+ runTestPointerDispatch<E>(M, dref, &dref.object.object);
+ }
+ {
+ typedef ObjectType const (TestType::*CMemPtr);
+ typedef ObjectType const E;
+ CMemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
+ runTestPointerDispatch<E>(M, dref, &dref.object.object);
+ }
+ {
+ typedef ObjectType volatile (TestType::*VMemPtr);
+ typedef ObjectType volatile E;
+ VMemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
+ runTestPointerDispatch<E>(M, dref, &dref.object.object);
+ }
+ {
+ typedef ObjectType const volatile (TestType::*CVMemPtr);
+ typedef ObjectType const volatile E;
+ CVMemPtr M = &TestType::object;
+ runTestDispatch<E>(M, obj, &obj.object);
+ runTestDispatch<E>(M, der, &der.object);
+ runTestDispatch<E>(M, dref2, &dref2.object.object);
+ runTestPointerDispatch<E>(M, obj_ptr, &obj_ptr->object);
+ runTestPointerDispatch<E>(M, der_ptr, &der_ptr->object);
+ runTestPointerDispatch<E>(M, dref, &dref.object.object);
+ }
+ }
+
+ template <class Expect, class Fn, class T>
+ void runTestDispatch(Fn M, T& obj, ObjectType* expect) {
+ runTest<Expect &> (M, C_<T&>(obj), expect);
+ runTest<Expect const&> (M, C_<T const&>(obj), expect);
+ runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect);
+ runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect);
+#if TEST_STD_VER >= 11
+ runTest<Expect&&> (M, C_<T&&>(obj), expect);
+ runTest<Expect const&&> (M, C_<T const&&>(obj), expect);
+ runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect);
+ runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect);
+#endif
+ }
+
+ template <class Expect, class Fn, class T>
+ void runTestPointerDispatch(Fn M, T& obj, ObjectType* expect) {
+ runTest<Expect&>(M, C_<T &>(obj), expect);
+ runTest<Expect&>(M, C_<T const&>(obj), expect);
+ runTest<Expect&>(M, C_<T volatile&>(obj), expect);
+ runTest<Expect&>(M, C_<T const volatile&>(obj), expect);
+#if TEST_STD_VER >= 11
+ runTest<Expect&>(M, C_<T&&>(obj), expect);
+ runTest<Expect&>(M, C_<T const&&>(obj), expect);
+ runTest<Expect&>(M, C_<T volatile&&>(obj), expect);
+ runTest<Expect&>(M, C_<T const volatile&&>(obj), expect);
+#endif
+ }
+
+ template <class Expect, class Fn, class T>
+#if TEST_STD_VER >= 11
+ void runTest(Fn M, T&& obj, ObjectType* expect) {
+#else
+ void runTest(Fn M, T& obj, ObjectType* expect ) {
+#endif
+ static_assert((std::is_same<
+ decltype(std::__invoke(M, std::forward<T>(obj))), Expect
+ >::value), "");
+ Expect e = std::__invoke(M, std::forward<T>(obj));
+ assert(&e == expect);
+ }
+};
+
+int main() {
+ TestCase<ArgType>::run();
+ TestCase<ArgType const>::run();
+ TestCase<ArgType volatile>::run();
+ TestCase<ArgType const volatile>::run();
+ TestCase<ArgType*>::run();
+}
\ No newline at end of file
diff --git a/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp b/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp
new file mode 100644
index 0000000..3f3c96a
--- /dev/null
+++ b/test/std/utilities/function.objects/func.require/bullet_5.pass.cpp
@@ -0,0 +1,327 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// INVOKE (f, t1, t2, ..., tN)
+
+//------------------------------------------------------------------------------
+// TESTING INVOKE(f, t1, t2, ..., tN)
+// - Bullet 5 -- f(t2, ..., tN)
+//
+// Overview:
+// Bullet 5 handles the cases where the first argument is not a member
+// function.
+//
+// Concerns:
+// 1) Different types of callable objects are supported. Including
+// 1a) Free Function pointers and references.
+// 1b) Classes which provide a call operator
+// 1c) lambdas
+// 2) The callable objects are perfect forwarded.
+// 3) The arguments are perfect forwarded.
+// 4) Signatures which include varargs are supported.
+// 5) In C++03 3 extra arguments should be allowed.
+//
+// Plan:
+// 1) Define a set of free functions, 'SF', and class types with call
+// operators, 'SC', that address concerns 4 and 5. The free functions should
+// return 'FunctionID::setUncheckedCall()' and the call operators should
+// return 'MethodID::setUncheckedCall()'.
+//
+// 2) For each function 'f' in 'SF' and 'SC' attempt to call 'f'
+// using the correct number of arguments and cv-ref qualifiers. Check that
+// 'f' has been called using 'FunctionID::checkCall()' if 'f' is a free
+// function and 'MethodID::checkCall()' otherwise.
+
+
+
+#include <functional>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "invoke_helpers.h"
+
+
+//==============================================================================
+// freeFunction03 - A C++03 free function.
+void*& freeFunction03() {
+ return FunctionPtrID<void*&(), freeFunction03>::setUncheckedCall();
+}
+
+void*& freeFunction03(...) {
+ return FunctionPtrID<void*&(...), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0>
+void*& freeFunction03(A0&) {
+ return FunctionPtrID<void*&(A0&), freeFunction03>::setUncheckedCall();
+}
+
+
+template <class A0>
+void*& freeFunction03(A0&, ...) {
+ return FunctionPtrID<void*&(A0&, ...), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0, class A1>
+void*& freeFunction03(A0&, A1&) {
+ return FunctionPtrID<void*&(A0&, A1&), freeFunction03>::setUncheckedCall();
+}
+
+
+template <class A0, class A1>
+void*& freeFunction03(A0&, A1&, ...) {
+ return FunctionPtrID<void*&(A0&, A1&, ...), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0, class A1, class A2>
+void*& freeFunction03(A0&, A1&, A2&) {
+ return FunctionPtrID<void*&(A0&, A1&, A2&), freeFunction03>::setUncheckedCall();
+}
+
+template <class A0, class A1, class A2>
+void*& freeFunction03(A0&, A1&, A2&, ...) {
+ return FunctionPtrID<void*&(A0&, A1&, A2&, ...), freeFunction03>::setUncheckedCall();
+}
+
+//==============================================================================
+// Functor03 - C++03 compatible functor object
+struct Functor03 {
+ typedef void*& R;
+ typedef Functor03 C;
+#define F(Args, ...) \
+ __VA_ARGS__ R operator() Args { return MethodID<R(C::*) Args>::setUncheckedCall(); } \
+ __VA_ARGS__ R operator() Args const { return MethodID<R(C::*) Args const>::setUncheckedCall(); } \
+ __VA_ARGS__ R operator() Args volatile { return MethodID<R(C::*) Args volatile>::setUncheckedCall(); } \
+ __VA_ARGS__ R operator() Args const volatile { return MethodID<R(C::*) Args const volatile>::setUncheckedCall(); }
+#
+ F(())
+ F((A0&), template <class A0>)
+ F((A0&, A1&), template <class A0, class A1>)
+ F((A0&, A1&, A2&), template <class A0, class A1, class A2>)
+#undef F
+public:
+ Functor03() {}
+private:
+ Functor03(Functor03 const&);
+ Functor03& operator=(Functor03 const&);
+};
+
+
+#if TEST_STD_VER >= 11
+
+//==============================================================================
+// freeFunction11 - A C++11 free function.
+template <class ...Args>
+void*& freeFunction11(Args&&...) {
+ return FunctionPtrID<void*&(Args&&...), freeFunction11>::setUncheckedCall();
+}
+
+template <class ...Args>
+void*& freeFunction11(Args&&...,...) {
+ return FunctionPtrID<void*&(Args&&...,...), freeFunction11>::setUncheckedCall();
+}
+
+//==============================================================================
+// Functor11 - C++11 reference qualified test member functions.
+struct Functor11 {
+ typedef void*& R;
+ typedef Functor11 C;
+
+#define F(CV) \
+ template <class ...Args> \
+ R operator()(Args&&...) CV { return MethodID<R(C::*)(Args&&...) CV>::setUncheckedCall(); }
+#
+ F(&)
+ F(const &)
+ F(volatile &)
+ F(const volatile &)
+ F(&&)
+ F(const &&)
+ F(volatile &&)
+ F(const volatile &&)
+#undef F
+public:
+ Functor11() {}
+private:
+ Functor11(Functor11 const&);
+ Functor11& operator=(Functor11 const&);
+};
+
+#endif // TEST_STD_VER >= 11
+
+
+//==============================================================================
+// TestCaseFunctorImp - A test case for an operator() class method.
+// ClassType - The type of the call object.
+// CallSig - The function signature of the call operator being tested.
+// Arity - the arity of 'CallSig'
+// ObjCaster - Transformation function applied to call object.
+// ArgCaster - Transformation function applied to the extra arguments.
+template <class ClassType, class CallSig, int Arity,
+ class ObjCaster, class ArgCaster = LValueCaster>
+struct TestCaseFunctorImp {
+public:
+ static void run() {
+ typedef MethodID<CallSig ClassType::*> MID;
+ BasicTest<MID, Arity, ObjCaster, ArgCaster> t;
+ typedef ClassType T;
+ typedef DerivedFromType<T> D;
+ T obj;
+ D der;
+ t.runTest(obj);
+ t.runTest(der);
+ }
+};
+
+//==============================================================================
+// TestCaseFreeFunction - A test case for a free function.
+// CallSig - The function signature of the free function being tested.
+// FnPtr - The function being tested.
+// Arity - the arity of 'CallSig'
+// ArgCaster - Transformation function to be applied to the extra arguments.
+template <class CallSig, CallSig* FnPtr, int Arity, class ArgCaster>
+struct TestCaseFreeFunction {
+public:
+ static void run() {
+ typedef FunctionPtrID<CallSig, FnPtr> FID;
+ BasicTest<FID, Arity, LValueCaster, ArgCaster> t;
+
+ DerefToType<CallSig*> deref_to(FnPtr);
+ DerefToType<CallSig&> deref_to_ref(*FnPtr);
+
+ t.runTest(FnPtr);
+ t.runTest(*FnPtr);
+ t.runTest(deref_to);
+ t.runTest(deref_to_ref);
+ }
+};
+
+//==============================================================================
+// runTest Helpers
+//==============================================================================
+#if TEST_STD_VER >= 11
+template <class Sig, int Arity, class ArgCaster>
+void runFunctionTestCase11() {
+ TestCaseFreeFunction<Sig, freeFunction11, Arity, ArgCaster>();
+}
+#endif
+
+template <class Sig, int Arity, class ArgCaster>
+void runFunctionTestCase() {
+ TestCaseFreeFunction<Sig, freeFunction03, Arity, ArgCaster>();
+#if TEST_STD_VER >= 11
+ runFunctionTestCase11<Sig, Arity, ArgCaster>();
+#endif
+}
+
+template <class Sig, int Arity, class ObjCaster, class ArgCaster>
+void runFunctorTestCase() {
+ TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster, ArgCaster>::run();
+}
+
+template <class Sig, int Arity, class ObjCaster>
+void runFunctorTestCase() {
+ TestCaseFunctorImp<Functor03, Sig, Arity, ObjCaster>::run();
+}
+
+#if TEST_STD_VER >= 11
+// runTestCase - Run a test case for C++11 class functor types
+template <class Sig, int Arity, class ObjCaster, class ArgCaster = LValueCaster>
+void runFunctorTestCase11() {
+ TestCaseFunctorImp<Functor11, Sig, Arity, ObjCaster, ArgCaster>::run();
+}
+#endif
+
+// runTestCase - Run a test case for both function and functor types.
+template <class Sig, int Arity, class ArgCaster>
+void runTestCase() {
+ runFunctionTestCase<Sig, Arity, ArgCaster>();
+ runFunctorTestCase <Sig, Arity, LValueCaster, ArgCaster>();
+};
+
+int main() {
+ typedef void*& R;
+ typedef ArgType A;
+ typedef A const CA;
+
+ runTestCase< R(), 0, LValueCaster >();
+ runTestCase< R(A&), 1, LValueCaster >();
+ runTestCase< R(A&, A&), 2, LValueCaster >();
+ runTestCase< R(A&, A&, A&), 3, LValueCaster >();
+ runTestCase< R(CA&), 1, ConstCaster >();
+ runTestCase< R(CA&, CA&), 2, ConstCaster >();
+ runTestCase< R(CA&, CA&, CA&), 3, ConstCaster >();
+
+ runFunctionTestCase<R(...), 0, LValueCaster >();
+ runFunctionTestCase<R(A&, ...), 1, LValueCaster >();
+ runFunctionTestCase<R(A&, A&, ...), 2, LValueCaster >();
+ runFunctionTestCase<R(A&, A&, A&, ...), 3, LValueCaster >();
+
+#if TEST_STD_VER >= 11
+ runFunctionTestCase11<R(A&&), 1, MoveCaster >();
+ runFunctionTestCase11<R(A&&, ...), 1, MoveCaster >();
+#endif
+
+ runFunctorTestCase<R(), 0, LValueCaster >();
+ runFunctorTestCase<R() const, 0, ConstCaster >();
+ runFunctorTestCase<R() volatile, 0, VolatileCaster >();
+ runFunctorTestCase<R() const volatile, 0, CVCaster >();
+ runFunctorTestCase<R(A&), 1, LValueCaster >();
+ runFunctorTestCase<R(A&) const, 1, ConstCaster >();
+ runFunctorTestCase<R(A&) volatile, 1, VolatileCaster >();
+ runFunctorTestCase<R(A&) const volatile, 1, CVCaster >();
+ runFunctorTestCase<R(A&, A&), 2, LValueCaster >();
+ runFunctorTestCase<R(A&, A&) const, 2, ConstCaster >();
+ runFunctorTestCase<R(A&, A&) volatile, 2, VolatileCaster >();
+ runFunctorTestCase<R(A&, A&) const volatile, 2, CVCaster >();
+ runFunctorTestCase<R(A&, A&, A&), 3, LValueCaster >();
+ runFunctorTestCase<R(A&, A&, A&) const, 3, ConstCaster >();
+ runFunctorTestCase<R(A&, A&, A&) volatile, 3, VolatileCaster >();
+ runFunctorTestCase<R(A&, A&, A&) const volatile, 3, CVCaster >();
+ {
+ typedef ConstCaster CC;
+ runFunctorTestCase<R(CA&), 1, LValueCaster, CC>();
+ runFunctorTestCase<R(CA&) const, 1, ConstCaster, CC>();
+ runFunctorTestCase<R(CA&) volatile, 1, VolatileCaster, CC>();
+ runFunctorTestCase<R(CA&) const volatile, 1, CVCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&), 2, LValueCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&) const, 2, ConstCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&) volatile, 2, VolatileCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&) const volatile, 2, CVCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&), 3, LValueCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&) const, 3, ConstCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&) volatile, 3, VolatileCaster, CC>();
+ runFunctorTestCase<R(CA&, CA&, CA&) const volatile, 3, CVCaster, CC>();
+ }
+
+#if TEST_STD_VER >= 11
+ runFunctorTestCase11<R() &, 0, LValueCaster >();
+ runFunctorTestCase11<R() const &, 0, ConstCaster >();
+ runFunctorTestCase11<R() volatile &, 0, VolatileCaster >();
+ runFunctorTestCase11<R() const volatile &, 0, CVCaster >();
+ runFunctorTestCase11<R() &&, 0, MoveCaster >();
+ runFunctorTestCase11<R() const &&, 0, MoveConstCaster >();
+ runFunctorTestCase11<R() volatile &&, 0, MoveVolatileCaster >();
+ runFunctorTestCase11<R() const volatile &&, 0, MoveCVCaster >();
+ {
+ typedef MoveCaster MC;
+ runFunctorTestCase11<R(A&&) &, 1, LValueCaster, MC>();
+ runFunctorTestCase11<R(A&&) const &, 1, ConstCaster, MC>();
+ runFunctorTestCase11<R(A&&) volatile &, 1, VolatileCaster, MC>();
+ runFunctorTestCase11<R(A&&) const volatile &, 1, CVCaster, MC>();
+ runFunctorTestCase11<R(A&&) &&, 1, MoveCaster, MC>();
+ runFunctorTestCase11<R(A&&) const &&, 1, MoveConstCaster, MC>();
+ runFunctorTestCase11<R(A&&) volatile &&, 1, MoveVolatileCaster, MC>();
+ runFunctorTestCase11<R(A&&) const volatile &&, 1, MoveCVCaster, MC>();
+ }
+#endif
+}
diff --git a/test/std/utilities/function.objects/func.require/invoke_helpers.h b/test/std/utilities/function.objects/func.require/invoke_helpers.h
new file mode 100644
index 0000000..0583b62
--- /dev/null
+++ b/test/std/utilities/function.objects/func.require/invoke_helpers.h
@@ -0,0 +1,317 @@
+#ifndef INVOKE_HELPERS_H
+#define INVOKE_HELPERS_H
+
+#include <type_traits>
+#include <cassert>
+#include <functional>
+
+#include "test_macros.h"
+
+template <int I>
+struct Int : public std::integral_constant<int, I> {};
+
+template <bool P>
+struct Bool : public std::integral_constant<bool, P> {};
+
+struct Q_None {
+ template <class T>
+ struct apply { typedef T type; };
+};
+
+struct Q_Const {
+ template <class T>
+ struct apply { typedef T const type; };
+};
+
+struct Q_Volatile {
+ template <class T>
+ struct apply { typedef T volatile type; };
+};
+
+struct Q_CV {
+ template <class T>
+ struct apply { typedef T const volatile type; };
+};
+
+// Caster - A functor object that performs cv-qualifier and value category
+// conversions.
+// QualTag - A metafunction type that applies cv-qualifiers to its argument.
+// RValue - True if the resulting object should be an RValue reference.
+// False otherwise.
+template <class QualTag, bool RValue = false>
+struct Caster {
+ template <class T>
+ struct apply {
+ typedef typename std::remove_reference<T>::type RawType;
+ typedef typename QualTag::template apply<RawType>::type CVType;
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<RValue,
+ CVType&&, CVType&
+ >::type type;
+#else
+ typedef CVType& type;
+#endif
+ };
+
+ template <class T>
+ typename apply<T>::type
+ operator()(T& obj) const {
+ typedef typename apply<T>::type OutType;
+ return static_cast<OutType>(obj);
+ }
+};
+
+typedef Caster<Q_None> LValueCaster;
+typedef Caster<Q_Const> ConstCaster;
+typedef Caster<Q_Volatile> VolatileCaster;
+typedef Caster<Q_CV> CVCaster;
+typedef Caster<Q_None, true> MoveCaster;
+typedef Caster<Q_Const, true> MoveConstCaster;
+typedef Caster<Q_Volatile, true> MoveVolatileCaster;
+typedef Caster<Q_CV, true> MoveCVCaster;
+
+// A shorter name for 'static_cast'
+template <class QualType, class Tp>
+QualType C_(Tp& v) { return static_cast<QualType>(v); };
+
+//==============================================================================
+// ArgType - A non-copyable type intended to be used as a dummy argument type
+// to test functions.
+struct ArgType {
+ int value;
+ explicit ArgType(int val = 0) : value(val) {}
+private:
+ ArgType(ArgType const&);
+ ArgType& operator=(ArgType const&);
+};
+
+//==============================================================================
+// DerivedFromBase - A type that derives from it's template argument 'Base'
+template <class Base>
+struct DerivedFromType : public Base {
+ DerivedFromType() : Base() {}
+ template <class Tp>
+ explicit DerivedFromType(Tp const& t) : Base(t) {}
+};
+
+//==============================================================================
+// DerefToType - A type that dereferences to it's template argument 'To'.
+// The cv-ref qualifiers of the 'DerefToType' object do not propagate
+// to the resulting 'To' object.
+template <class To>
+struct DerefToType {
+ To object;
+
+ DerefToType() {}
+
+ template <class Up>
+ explicit DerefToType(Up const& val) : object(val) {}
+
+ To& operator*() const volatile { return const_cast<To&>(object); }
+};
+
+//==============================================================================
+// DerefPropToType - A type that dereferences to it's template argument 'To'.
+// The cv-ref qualifiers of the 'DerefPropToType' object propagate
+// to the resulting 'To' object.
+template <class To>
+struct DerefPropType {
+ To object;
+
+ DerefPropType() {}
+
+ template <class Up>
+ explicit DerefPropType(Up const& val) : object(val) {}
+
+#if TEST_STD_VER < 11
+ To& operator*() { return object; }
+ To const& operator*() const { return object; }
+ To volatile& operator*() volatile { return object; }
+ To const volatile& operator*() const volatile { return object; }
+#else
+ To& operator*() & { return object; }
+ To const& operator*() const & { return object; }
+ To volatile& operator*() volatile & { return object; }
+ To const volatile& operator*() const volatile & { return object; }
+ To&& operator*() && { return static_cast<To &&>(object); }
+ To const&& operator*() const && { return static_cast<To const&&>(object); }
+ To volatile&& operator*() volatile && { return static_cast<To volatile&&>(object); }
+ To const volatile&& operator*() const volatile && { return static_cast<To const volatile&&>(object); }
+#endif
+};
+
+//==============================================================================
+// MethodID - A type that uniquely identifies a member function for a class.
+// This type is used to communicate between the member functions being tested
+// and the tests invoking them.
+// - Test methods should call 'setUncheckedCall()' whenever they are invoked.
+// - Tests consume the unchecked call using checkCall(<return-value>)` to assert
+// that the method has been called and that the return value of `__invoke`
+// matches what the method actually returned.
+template <class T>
+struct MethodID {
+ typedef void* IDType;
+
+ static int dummy; // A dummy memory location.
+ static void* id; // The "ID" is the value of this pointer.
+ static bool unchecked_call; // Has a call happened that has not been checked.
+
+ static void*& setUncheckedCall() {
+ assert(unchecked_call == false);
+ unchecked_call = true;
+ return id;
+ }
+
+ static bool checkCalled(void*& return_value) {
+ bool old = unchecked_call;
+ unchecked_call = false;
+ return old && id == return_value && &id == &return_value;
+ }
+};
+
+template <class T> int MethodID<T>::dummy = 0;
+template <class T> void* MethodID<T>::id = (void*)&MethodID<T>::dummy;
+template <class T> bool MethodID<T>::unchecked_call = false;
+
+
+//==============================================================================
+// FunctionPtrID - Like MethodID but for free function pointers.
+template <class T, T*>
+struct FunctionPtrID {
+ static int dummy; // A dummy memory location.
+ static void* id; // The "ID" is the value of this pointer.
+ static bool unchecked_call; // Has a call happened that has not been checked.
+
+ static void*& setUncheckedCall() {
+ assert(unchecked_call == false);
+ unchecked_call = true;
+ return id;
+ }
+
+ static bool checkCalled(void*& return_value) {
+ bool old = unchecked_call;
+ unchecked_call = false;
+ return old && id == return_value && &id == &return_value;
+ }
+};
+
+template <class T, T* Ptr> int FunctionPtrID<T, Ptr>::dummy = 0;
+template <class T, T* Ptr> void* FunctionPtrID<T, Ptr>::id = (void*)&FunctionPtrID<T, Ptr>::dummy;
+template <class T, T* Ptr> bool FunctionPtrID<T, Ptr>::unchecked_call = false;
+
+//==============================================================================
+// BasicTest - The basic test structure for everything except
+// member object pointers.
+// ID - The "Function Identifier" type used either MethodID or FunctionPtrID.
+// Arity - The Arity of the call signature.
+// ObjectCaster - The object transformation functor type.
+// ArgCaster - The extra argument transformation functor type.
+template <class ID, int Arity, class ObjectCaster = LValueCaster,
+ class ArgCaster = LValueCaster>
+struct BasicTest {
+ template <class ObjectT>
+ void runTest(ObjectT& object) {
+ Int<Arity> A;
+ runTestImp(A, object);
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTest(MethodPtr ptr, ObjectT& object) {
+ Int<Arity> A;
+ runTestImp(A, ptr, object);
+ }
+
+private:
+ typedef void*& CallRet;
+ ObjectCaster object_cast;
+ ArgCaster arg_cast;
+ ArgType a0, a1, a2;
+
+ //==========================================================================
+ // BULLET 1 AND 2 TEST METHODS
+ //==========================================================================
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<0>, MethodPtr ptr, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object));
+ assert(ID::checkCalled(ret));
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<1>, MethodPtr ptr, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0));
+ assert(ID::checkCalled(ret));
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<2>, MethodPtr ptr, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1));
+ assert(ID::checkCalled(ret));
+ }
+
+ template <class MethodPtr, class ObjectT>
+ void runTestImp(Int<3>, MethodPtr ptr, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
+ assert(ID::checkCalled(ret));
+ }
+
+ //==========================================================================
+ // BULLET 5 TEST METHODS
+ //==========================================================================
+ template <class ObjectT>
+ void runTestImp(Int<0>, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object));
+ assert(ID::checkCalled(ret));
+ }
+
+ template <class ObjectT>
+ void runTestImp(Int<1>, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object), arg_cast(a0)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0));
+ assert(ID::checkCalled(ret));
+ }
+
+ template <class ObjectT>
+ void runTestImp(Int<2>, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1));
+ assert(ID::checkCalled(ret));
+ }
+
+ template <class ObjectT>
+ void runTestImp(Int<3>, ObjectT& object) {
+ static_assert((std::is_same<
+ decltype(std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)))
+ , CallRet>::value), "");
+ assert(ID::unchecked_call == false);
+ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2));
+ assert(ID::checkCalled(ret));
+ }
+};
+
+#endif // INVOKE_HELPERS_H
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
index cd86e4c..82a6f6c 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
@@ -11,7 +11,7 @@
// class function<R(ArgTypes...)>
-// function(nullptr_t);
+// function(F);
#include <functional>
#include <cassert>
@@ -87,4 +87,8 @@
assert(f.target<int(*)(int)>() != 0);
f(1);
}
+ {
+ std::function <void()> f(static_cast<void (*)()>(0));
+ assert(!f);
+ }
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
index 4feac30..f97e34d 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
@@ -16,10 +16,12 @@
#include <functional>
#include <cassert>
-#include "test_allocator.h"
+#include "min_allocator.h"
int main()
{
- std::function<int(int)> f(std::allocator_arg, test_allocator<int>());
+ {
+ std::function<int(int)> f(std::allocator_arg, bare_allocator<int>());
assert(!f);
+ }
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
index 28e44a6..352ecfc 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
@@ -16,85 +16,91 @@
#include <functional>
#include <cassert>
+#include "min_allocator.h"
#include "test_allocator.h"
+#include "count_new.hpp"
+#include "../function_types.h"
-class A
+class DummyClass {};
+
+template <class FuncType, class AllocType>
+void test_FunctionObject(AllocType& alloc)
{
- int data_[10];
-public:
- static int count;
-
- A()
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- ++count;
- for (int i = 0; i < 10; ++i)
- data_[i] = i;
+ FunctionObject target;
+ assert(FunctionObject::count == 1);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ std::function<FuncType> f2(std::allocator_arg, alloc, target);
+ assert(FunctionObject::count == 2);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(f2.template target<FunctionObject>());
+ assert(f2.template target<FuncType>() == 0);
+ assert(f2.template target<FuncType*>() == 0);
}
+ assert(FunctionObject::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
- A(const A&) {++count;}
- ~A() {--count;}
-
- int operator()(int i) const
+template <class FuncType, class AllocType>
+void test_FreeFunction(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- for (int j = 0; j < 10; ++j)
- i += data_[j];
- return i;
+ FuncType* target = &FreeFunction;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ std::function<FuncType> f2(std::allocator_arg, alloc, target);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f2.template target<FuncType*>());
+ assert(*f2.template target<FuncType*>() == target);
+ assert(f2.template target<FuncType>() == 0);
+ assert(f2.template target<DummyClass>() == 0);
}
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
- int foo(int) const {return 1;}
-};
+template <class TargetType, class FuncType, class AllocType>
+void test_MemFunClass(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ TargetType target = &MemFunClass::foo;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ std::function<FuncType> f2(std::allocator_arg, alloc, target);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f2.template target<TargetType>());
+ assert(*f2.template target<TargetType>() == target);
+ assert(f2.template target<FuncType*>() == 0);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
-int A::count = 0;
+template <class Alloc>
+void test_for_alloc(Alloc& alloc) {
+ test_FunctionObject<int()>(alloc);
+ test_FunctionObject<int(int)>(alloc);
+ test_FunctionObject<int(int, int)>(alloc);
+ test_FunctionObject<int(int, int, int)>(alloc);
-int g(int) {return 0;}
+ test_FreeFunction<int()>(alloc);
+ test_FreeFunction<int(int)>(alloc);
+ test_FreeFunction<int(int, int)>(alloc);
+ test_FreeFunction<int(int, int, int)>(alloc);
-class Foo {
-public:
- void bar(int k) { }
-};
+ test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
+}
int main()
{
{
- std::function<int(int)> f(std::allocator_arg, test_allocator<A>(), A());
- assert(A::count == 1);
- assert(f.target<A>());
- assert(f.target<int(*)(int)>() == 0);
- }
- assert(A::count == 0);
- {
- std::function<int(int)> f(std::allocator_arg, test_allocator<int(*)(int)>(), g);
- assert(f.target<int(*)(int)>());
- assert(f.target<A>() == 0);
+ bare_allocator<DummyClass> bare_alloc;
+ test_for_alloc(bare_alloc);
}
{
- std::function<int(int)> f(std::allocator_arg, test_allocator<int(*)(int)>(),
- (int (*)(int))0);
- assert(!f);
- assert(f.target<int(*)(int)>() == 0);
- assert(f.target<A>() == 0);
- }
- {
- std::function<int(const A*, int)> f(std::allocator_arg,
- test_allocator<int(A::*)(int)const>(),
- &A::foo);
- assert(f);
- assert(f.target<int (A::*)(int) const>() != 0);
- }
-#if __cplusplus >= 201103L
- {
- Foo f;
- std::function<void(int)> fun = std::bind(&Foo::bar, &f, std::placeholders::_1);
- fun(10);
- }
-#endif
- {
- std::function<void(int)> fun(std::allocator_arg,
- test_allocator<int(*)(int)>(),
- &g);
- assert(fun);
- assert(fun.target<int(*)(int)>() != 0);
- fun(10);
+ non_default_test_allocator<DummyClass> non_default_alloc(42);
+ test_for_alloc(non_default_alloc);
}
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
index bb8feff..371eb98 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
@@ -17,83 +17,108 @@
#include <functional>
#include <cassert>
+#include "min_allocator.h"
#include "test_allocator.h"
#include "count_new.hpp"
+#include "../function_types.h"
-class A
+class DummyClass {};
+
+template <class FuncType, class AllocType>
+void test_FunctionObject(AllocType& alloc)
{
- int data_[10];
-public:
- static int count;
-
- A()
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- ++count;
- for (int i = 0; i < 10; ++i)
- data_[i] = i;
+ // Construct function from FunctionObject.
+ std::function<FuncType> f = FunctionObject();
+ assert(FunctionObject::count == 1);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(f.template target<FunctionObject>());
+ assert(f.template target<FuncType>() == 0);
+ assert(f.template target<FuncType*>() == 0);
+ // Copy function with allocator
+ std::function<FuncType> f2(std::allocator_arg, alloc, f);
+ assert(FunctionObject::count == 2);
+ assert(globalMemCounter.checkOutstandingNewEq(2));
+ assert(f2.template target<FunctionObject>());
+ assert(f2.template target<FuncType>() == 0);
+ assert(f2.template target<FuncType*>() == 0);
}
+ assert(FunctionObject::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
- A(const A&) {++count;}
-
- ~A() {--count;}
-
- int operator()(int i) const
+template <class FuncType, class AllocType>
+void test_FreeFunction(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- for (int j = 0; j < 10; ++j)
- i += data_[j];
- return i;
+ // Construct function from function pointer.
+ FuncType* target = &FreeFunction;
+ std::function<FuncType> f = target;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f.template target<FuncType*>());
+ assert(*f.template target<FuncType*>() == target);
+ assert(f.template target<FuncType>() == 0);
+ // Copy function with allocator
+ std::function<FuncType> f2(std::allocator_arg, alloc, f);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f2.template target<FuncType*>());
+ assert(*f2.template target<FuncType*>() == target);
+ assert(f2.template target<FuncType>() == 0);
}
-};
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
-int A::count = 0;
+template <class TargetType, class FuncType, class AllocType>
+void test_MemFunClass(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ // Construct function from function pointer.
+ TargetType target = &MemFunClass::foo;
+ std::function<FuncType> f = target;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f.template target<TargetType>());
+ assert(*f.template target<TargetType>() == target);
+ assert(f.template target<FuncType*>() == 0);
+ // Copy function with allocator
+ std::function<FuncType> f2(std::allocator_arg, alloc, f);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f2.template target<TargetType>());
+ assert(*f2.template target<TargetType>() == target);
+ assert(f2.template target<FuncType*>() == 0);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
-int g(int) {return 0;}
+template <class Alloc>
+void test_for_alloc(Alloc& alloc)
+{
+ // Large FunctionObject -- Allocation should occur
+ test_FunctionObject<int()>(alloc);
+ test_FunctionObject<int(int)>(alloc);
+ test_FunctionObject<int(int, int)>(alloc);
+ test_FunctionObject<int(int, int, int)>(alloc);
+ // Free function -- No allocation should occur
+ test_FreeFunction<int()>(alloc);
+ test_FreeFunction<int(int)>(alloc);
+ test_FreeFunction<int(int, int)>(alloc);
+ test_FreeFunction<int(int, int, int)>(alloc);
+ // Member function -- No allocation should occur.
+ test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
+}
int main()
{
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
- std::function<int(int)> f = A();
- assert(A::count == 1);
- assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(f.target<A>());
- assert(f.target<int(*)(int)>() == 0);
- std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), f);
- assert(A::count == 2);
- assert(globalMemCounter.checkOutstandingNewEq(2));
- assert(f2.target<A>());
- assert(f2.target<int(*)(int)>() == 0);
- }
- assert(A::count == 0);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
- std::function<int(int)> f = g;
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f.target<int(*)(int)>());
- assert(f.target<A>() == 0);
- std::function<int(int)> f2(std::allocator_arg, test_allocator<int(*)(int)>(), f);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>());
- assert(f2.target<A>() == 0);
- }
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
- assert(globalMemCounter.checkOutstandingNewEq(0));
- non_default_test_allocator<std::function<int(int)> > al(1);
- std::function<int(int)> f2(std::allocator_arg, al, g);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>());
- assert(f2.target<A>() == 0);
- }
- assert(globalMemCounter.checkOutstandingNewEq(0));
- {
- std::function<int(int)> f;
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f.target<int(*)(int)>() == 0);
- assert(f.target<A>() == 0);
- std::function<int(int)> f2(std::allocator_arg, test_allocator<int>(), f);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>() == 0);
- assert(f2.target<A>() == 0);
- }
+ {
+ bare_allocator<DummyClass> alloc;
+ test_for_alloc(alloc);
+ }
+ {
+ non_default_test_allocator<DummyClass> alloc(42);
+ test_for_alloc(alloc);
+ }
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
index 956136b..2350f92 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
@@ -16,10 +16,10 @@
#include <functional>
#include <cassert>
-#include "test_allocator.h"
+#include "min_allocator.h"
int main()
{
- std::function<int(int)> f(std::allocator_arg, test_allocator<int>(), nullptr);
+ std::function<int(int)> f(std::allocator_arg, bare_allocator<int>(), nullptr);
assert(!f);
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
index 15b7c8b..aa6b743 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
@@ -16,7 +16,7 @@
#include <functional>
#include <cassert>
-#include "test_allocator.h"
+#include "min_allocator.h"
#include "count_new.hpp"
class A
@@ -56,7 +56,7 @@
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f.target<A>());
assert(f.target<int(*)(int)>() == 0);
- std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), std::move(f));
+ std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), std::move(f));
assert(A::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
assert(f2.target<A>());
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp
index 6dcd285..61eda72 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.fail.cpp
@@ -30,13 +30,13 @@
{
// member data pointer
{
- int A_int_1::*fp = &A_int_1::data_;
- A_int_1 a;
- std::function<int& (const A_int_1*)> r2(fp);
- const A_int_1* ap = &a;
- assert(r2(ap) == 6);
- r2(ap) = 7;
- assert(r2(ap) == 7);
+ int A_int_1::*fp = &A_int_1::data_;
+ A_int_1 a;
+ std::function<int& (const A_int_1*)> r2(fp);
+ const A_int_1* ap = &a;
+ assert(r2(ap) == 6);
+ r2(ap) = 7;
+ assert(r2(ap) == 7);
}
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp
index 31b80c3..cc4315c 100644
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp
@@ -16,8 +16,85 @@
#include <functional>
#include <cassert>
+
int count = 0;
+
+// 0 args, return int
+
+int f_int_0()
+{
+ return 3;
+}
+
+struct A_int_0
+{
+ int operator()() {return 4;}
+};
+
+void test_int_0()
+{
+ // function
+ {
+ std::function<int ()> r1(f_int_0);
+ assert(r1() == 3);
+ }
+ // function pointer
+ {
+ int (*fp)() = f_int_0;
+ std::function<int ()> r1(fp);
+ assert(r1() == 3);
+ }
+ // functor
+ {
+ A_int_0 a0;
+ std::function<int ()> r1(a0);
+ assert(r1() == 4);
+ }
+}
+
+
+// 0 args, return void
+
+void f_void_0()
+{
+ ++count;
+}
+
+struct A_void_0
+{
+ void operator()() {++count;}
+};
+
+void
+test_void_0()
+{
+ int save_count = count;
+ // function
+ {
+ std::function<void ()> r1(f_void_0);
+ r1();
+ assert(count == save_count+1);
+ save_count = count;
+ }
+ // function pointer
+ {
+ void (*fp)() = f_void_0;
+ std::function<void ()> r1(fp);
+ r1();
+ assert(count == save_count+1);
+ save_count = count;
+ }
+ // functor
+ {
+ A_void_0 a0;
+ std::function<void ()> r1(a0);
+ r1();
+ assert(count == save_count+1);
+ save_count = count;
+ }
+}
+
// 1 arg, return void
void f_void_1(int i)
@@ -42,57 +119,57 @@
int save_count = count;
// function
{
- std::function<void (int)> r1(f_void_1);
- int i = 2;
- r1(i);
- assert(count == save_count+2);
- save_count = count;
+ std::function<void (int)> r1(f_void_1);
+ int i = 2;
+ r1(i);
+ assert(count == save_count+2);
+ save_count = count;
}
// function pointer
{
- void (*fp)(int) = f_void_1;
- std::function<void (int)> r1(fp);
- int i = 3;
- r1(i);
- assert(count == save_count+3);
- save_count = count;
+ void (*fp)(int) = f_void_1;
+ std::function<void (int)> r1(fp);
+ int i = 3;
+ r1(i);
+ assert(count == save_count+3);
+ save_count = count;
}
// functor
{
- A_void_1 a0;
- std::function<void (int)> r1(a0);
- int i = 4;
- r1(i);
- assert(count == save_count+4);
- save_count = count;
+ A_void_1 a0;
+ std::function<void (int)> r1(a0);
+ int i = 4;
+ r1(i);
+ assert(count == save_count+4);
+ save_count = count;
}
// member function pointer
{
- void (A_void_1::*fp)() = &A_void_1::mem1;
- std::function<void (A_void_1)> r1(fp);
- A_void_1 a;
- r1(a);
- assert(count == save_count+1);
- save_count = count;
- A_void_1* ap = &a;
- std::function<void (A_void_1*)> r2 = fp;
- r2(ap);
- assert(count == save_count+1);
- save_count = count;
+ void (A_void_1::*fp)() = &A_void_1::mem1;
+ std::function<void (A_void_1)> r1(fp);
+ A_void_1 a;
+ r1(a);
+ assert(count == save_count+1);
+ save_count = count;
+ A_void_1* ap = &a;
+ std::function<void (A_void_1*)> r2 = fp;
+ r2(ap);
+ assert(count == save_count+1);
+ save_count = count;
}
// const member function pointer
{
- void (A_void_1::*fp)() const = &A_void_1::mem2;
- std::function<void (A_void_1)> r1(fp);
- A_void_1 a;
- r1(a);
- assert(count == save_count+1);
- save_count = count;
- std::function<void (A_void_1*)> r2(fp);
- A_void_1* ap = &a;
- r2(ap);
- assert(count == save_count+1);
- save_count = count;
+ void (A_void_1::*fp)() const = &A_void_1::mem2;
+ std::function<void (A_void_1)> r1(fp);
+ A_void_1 a;
+ r1(a);
+ assert(count == save_count+1);
+ save_count = count;
+ std::function<void (A_void_1*)> r2(fp);
+ A_void_1* ap = &a;
+ r2(ap);
+ assert(count == save_count+1);
+ save_count = count;
}
}
@@ -121,57 +198,57 @@
{
// function
{
- std::function<int (int)> r1(f_int_1);
- int i = 2;
- assert(r1(i) == 3);
+ std::function<int (int)> r1(f_int_1);
+ int i = 2;
+ assert(r1(i) == 3);
}
// function pointer
{
- int (*fp)(int) = f_int_1;
- std::function<int (int)> r1(fp);
- int i = 3;
- assert(r1(i) == 4);
+ int (*fp)(int) = f_int_1;
+ std::function<int (int)> r1(fp);
+ int i = 3;
+ assert(r1(i) == 4);
}
// functor
{
- A_int_1 a0;
- std::function<int (int)> r1(a0);
- int i = 4;
- assert(r1(i) == 3);
+ A_int_1 a0;
+ std::function<int (int)> r1(a0);
+ int i = 4;
+ assert(r1(i) == 3);
}
// member function pointer
{
- int (A_int_1::*fp)() = &A_int_1::mem1;
- std::function<int (A_int_1)> r1(fp);
- A_int_1 a;
- assert(r1(a) == 3);
- std::function<int (A_int_1*)> r2(fp);
- A_int_1* ap = &a;
- assert(r2(ap) == 3);
+ int (A_int_1::*fp)() = &A_int_1::mem1;
+ std::function<int (A_int_1)> r1(fp);
+ A_int_1 a;
+ assert(r1(a) == 3);
+ std::function<int (A_int_1*)> r2(fp);
+ A_int_1* ap = &a;
+ assert(r2(ap) == 3);
}
// const member function pointer
{
- int (A_int_1::*fp)() const = &A_int_1::mem2;
- std::function<int (A_int_1)> r1(fp);
- A_int_1 a;
- assert(r1(a) == 4);
- std::function<int (A_int_1*)> r2(fp);
- A_int_1* ap = &a;
- assert(r2(ap) == 4);
+ int (A_int_1::*fp)() const = &A_int_1::mem2;
+ std::function<int (A_int_1)> r1(fp);
+ A_int_1 a;
+ assert(r1(a) == 4);
+ std::function<int (A_int_1*)> r2(fp);
+ A_int_1* ap = &a;
+ assert(r2(ap) == 4);
}
// member data pointer
{
- int A_int_1::*fp = &A_int_1::data_;
- std::function<int& (A_int_1&)> r1(fp);
- A_int_1 a;
- assert(r1(a) == 5);
- r1(a) = 6;
- assert(r1(a) == 6);
- std::function<int& (A_int_1*)> r2(fp);
- A_int_1* ap = &a;
- assert(r2(ap) == 6);
- r2(ap) = 7;
- assert(r2(ap) == 7);
+ int A_int_1::*fp = &A_int_1::data_;
+ std::function<int& (A_int_1&)> r1(fp);
+ A_int_1 a;
+ assert(r1(a) == 5);
+ r1(a) = 6;
+ assert(r1(a) == 6);
+ std::function<int& (A_int_1*)> r2(fp);
+ A_int_1* ap = &a;
+ assert(r2(ap) == 6);
+ r2(ap) = 7;
+ assert(r2(ap) == 7);
}
}
@@ -199,62 +276,62 @@
int save_count = count;
// function
{
- std::function<void (int, int)> r1(f_void_2);
- int i = 2;
- int j = 3;
- r1(i, j);
- assert(count == save_count+5);
- save_count = count;
+ std::function<void (int, int)> r1(f_void_2);
+ int i = 2;
+ int j = 3;
+ r1(i, j);
+ assert(count == save_count+5);
+ save_count = count;
}
// function pointer
{
- void (*fp)(int, int) = f_void_2;
- std::function<void (int, int)> r1(fp);
- int i = 3;
- int j = 4;
- r1(i, j);
- assert(count == save_count+7);
- save_count = count;
+ void (*fp)(int, int) = f_void_2;
+ std::function<void (int, int)> r1(fp);
+ int i = 3;
+ int j = 4;
+ r1(i, j);
+ assert(count == save_count+7);
+ save_count = count;
}
// functor
{
- A_void_2 a0;
- std::function<void (int, int)> r1(a0);
- int i = 4;
- int j = 5;
- r1(i, j);
- assert(count == save_count+9);
- save_count = count;
+ A_void_2 a0;
+ std::function<void (int, int)> r1(a0);
+ int i = 4;
+ int j = 5;
+ r1(i, j);
+ assert(count == save_count+9);
+ save_count = count;
}
// member function pointer
{
- void (A_void_2::*fp)(int) = &A_void_2::mem1;
- std::function<void (A_void_2, int)> r1(fp);
- A_void_2 a;
- int i = 3;
- r1(a, i);
- assert(count == save_count+3);
- save_count = count;
- std::function<void (A_void_2*, int)> r2(fp);
- A_void_2* ap = &a;
- r2(ap, i);
- assert(count == save_count+3);
- save_count = count;
+ void (A_void_2::*fp)(int) = &A_void_2::mem1;
+ std::function<void (A_void_2, int)> r1(fp);
+ A_void_2 a;
+ int i = 3;
+ r1(a, i);
+ assert(count == save_count+3);
+ save_count = count;
+ std::function<void (A_void_2*, int)> r2(fp);
+ A_void_2* ap = &a;
+ r2(ap, i);
+ assert(count == save_count+3);
+ save_count = count;
}
// const member function pointer
{
- void (A_void_2::*fp)(int) const = &A_void_2::mem2;
- std::function<void (A_void_2, int)> r1(fp);
- A_void_2 a;
- int i = 4;
- r1(a, i);
- assert(count == save_count+4);
- save_count = count;
- std::function<void (A_void_2*, int)> r2(fp);
- A_void_2* ap = &a;
- r2(ap, i);
- assert(count == save_count+4);
- save_count = count;
+ void (A_void_2::*fp)(int) const = &A_void_2::mem2;
+ std::function<void (A_void_2, int)> r1(fp);
+ A_void_2 a;
+ int i = 4;
+ r1(a, i);
+ assert(count == save_count+4);
+ save_count = count;
+ std::function<void (A_void_2*, int)> r2(fp);
+ A_void_2* ap = &a;
+ r2(ap, i);
+ assert(count == save_count+4);
+ save_count = count;
}
}
@@ -276,60 +353,61 @@
int mem2(int i) const {return i+2;}
};
-void
-testint_2()
+void test_int_2()
{
// function
{
- std::function<int (int, int)> r1(f_int_2);
- int i = 2;
- int j = 3;
- assert(r1(i, j) == i+j);
+ std::function<int (int, int)> r1(f_int_2);
+ int i = 2;
+ int j = 3;
+ assert(r1(i, j) == i+j);
}
// function pointer
{
- int (*fp)(int, int) = f_int_2;
- std::function<int (int, int)> r1(fp);
- int i = 3;
- int j = 4;
- assert(r1(i, j) == i+j);
+ int (*fp)(int, int) = f_int_2;
+ std::function<int (int, int)> r1(fp);
+ int i = 3;
+ int j = 4;
+ assert(r1(i, j) == i+j);
}
// functor
{
- A_int_2 a0;
- std::function<int (int, int)> r1(a0);
- int i = 4;
- int j = 5;
- assert(r1(i, j) == i+j);
+ A_int_2 a0;
+ std::function<int (int, int)> r1(a0);
+ int i = 4;
+ int j = 5;
+ assert(r1(i, j) == i+j);
}
// member function pointer
{
- int(A_int_2::*fp)(int) = &A_int_2::mem1;
- std::function<int (A_int_2, int)> r1(fp);
- A_int_2 a;
- int i = 3;
- assert(r1(a, i) == i+1);
- std::function<int (A_int_2*, int)> r2(fp);
- A_int_2* ap = &a;
- assert(r2(ap, i) == i+1);
+ int(A_int_2::*fp)(int) = &A_int_2::mem1;
+ std::function<int (A_int_2, int)> r1(fp);
+ A_int_2 a;
+ int i = 3;
+ assert(r1(a, i) == i+1);
+ std::function<int (A_int_2*, int)> r2(fp);
+ A_int_2* ap = &a;
+ assert(r2(ap, i) == i+1);
}
// const member function pointer
{
- int (A_int_2::*fp)(int) const = &A_int_2::mem2;
- std::function<int (A_int_2, int)> r1(fp);
- A_int_2 a;
- int i = 4;
- assert(r1(a, i) == i+2);
- std::function<int (A_int_2*, int)> r2(fp);
- A_int_2* ap = &a;
- assert(r2(ap, i) == i+2);
+ int (A_int_2::*fp)(int) const = &A_int_2::mem2;
+ std::function<int (A_int_2, int)> r1(fp);
+ A_int_2 a;
+ int i = 4;
+ assert(r1(a, i) == i+2);
+ std::function<int (A_int_2*, int)> r2(fp);
+ A_int_2* ap = &a;
+ assert(r2(ap, i) == i+2);
}
}
int main()
{
+ test_void_0();
+ test_int_0();
test_void_1();
test_int_1();
test_void_2();
- testint_2();
+ test_int_2();
}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_int_0.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_int_0.pass.cpp
deleted file mode 100644
index 67b4ec2..0000000
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_int_0.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <functional>
-
-// class function<R(ArgTypes...)>
-
-// R operator()(ArgTypes... args) const
-
-#include <functional>
-#include <cassert>
-
-// 0 args, return int
-
-int count = 0;
-
-int f_int_0()
-{
- return 3;
-}
-
-struct A_int_0
-{
- int operator()() {return 4;}
-};
-
-void
-test_int_0()
-{
- // function
- {
- std::function<int ()> r1(f_int_0);
- assert(r1() == 3);
- }
- // function pointer
- {
- int (*fp)() = f_int_0;
- std::function<int ()> r1(fp);
- assert(r1() == 3);
- }
- // functor
- {
- A_int_0 a0;
- std::function<int ()> r1(a0);
- assert(r1() == 4);
- }
-}
-
-int main()
-{
- test_int_0();
-}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_no_variadics.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_no_variadics.pass.cpp
deleted file mode 100644
index c0a14fd..0000000
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_no_variadics.pass.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <functional>
-
-// class function<R()>
-
-// Test that we properly return both values and void for all non-variadic
-// overloads of function::operator()(...)
-
-#define _LIBCPP_HAS_NO_VARIADICS
-#include <functional>
-#include <cassert>
-
-int foo0() { return 42; }
-int foo1(int) { return 42; }
-int foo2(int, int) { return 42; }
-int foo3(int, int, int) { return 42; }
-
-int main()
-{
- {
- std::function<int()> f(&foo0);
- assert(f() == 42);
- }
- {
- std::function<int(int)> f(&foo1);
- assert(f(1) == 42);
- }
- {
- std::function<int(int, int)> f(&foo2);
- assert(f(1, 1) == 42);
- }
- {
- std::function<int(int, int, int)> f(&foo3);
- assert(f(1, 1, 1) == 42);
- }
- {
- std::function<void()> f(&foo0);
- f();
- }
- {
- std::function<void(int)> f(&foo1);
- f(1);
- }
- {
- std::function<void(int, int)> f(&foo2);
- f(1, 1);
- }
- {
- std::function<void(int, int, int)> f(&foo3);
- f(1, 1, 1);
- }
-}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_void_0.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_void_0.pass.cpp
deleted file mode 100644
index a820cb1..0000000
--- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke_void_0.pass.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <functional>
-
-// class function<R(ArgTypes...)>
-
-// R operator()(ArgTypes... args) const
-
-#include <functional>
-#include <new>
-#include <cstdlib>
-#include <cassert>
-
-// 0 args, return void
-
-int count = 0;
-
-void f_void_0()
-{
- ++count;
-}
-
-struct A_void_0
-{
- void operator()() {++count;}
-};
-
-void
-test_void_0()
-{
- int save_count = count;
- // function
- {
- std::function<void ()> r1(f_void_0);
- r1();
- assert(count == save_count+1);
- save_count = count;
- }
- // function pointer
- {
- void (*fp)() = f_void_0;
- std::function<void ()> r1(fp);
- r1();
- assert(count == save_count+1);
- save_count = count;
- }
- // functor
- {
- A_void_0 a0;
- std::function<void ()> r1(a0);
- r1();
- assert(count == save_count+1);
- save_count = count;
- }
-}
-
-int main()
-{
- test_void_0();
-}
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h b/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h
new file mode 100644
index 0000000..55eb80f
--- /dev/null
+++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/function_types.h
@@ -0,0 +1,57 @@
+#ifndef FUNCTION_TYPES_H
+#define FUNCTION_TYPES_H
+
+
+class FunctionObject
+{
+ int data_[10]; // dummy variable to prevent small object optimization in
+ // std::function
+public:
+ static int count;
+
+ FunctionObject() {
+ ++count;
+ for (int i = 0; i < 10; ++i) data_[i] = i;
+ }
+
+ FunctionObject(const FunctionObject&) {++count;}
+ ~FunctionObject() {--count; ((void)data_); }
+
+ int operator()() const { return 42; }
+ int operator()(int i) const { return i; }
+ int operator()(int i, int) const { return i; }
+ int operator()(int i, int, int) const { return i; }
+};
+
+int FunctionObject::count = 0;
+
+class MemFunClass
+{
+ int data_[10]; // dummy variable to prevent small object optimization in
+ // std::function
+public:
+ static int count;
+
+ MemFunClass() {
+ ++count;
+ for (int i = 0; i < 10; ++i) data_[i] = 0;
+ }
+
+ MemFunClass(const MemFunClass&) {++count; ((void)data_); }
+
+ ~MemFunClass() {--count;}
+
+ int foo() const { return 42; }
+ int foo(int i) const { return i; }
+ int foo(int i, int) const { return i; }
+ int foo(int i, int, int) const { return i; }
+};
+
+int MemFunClass::count = 0;
+
+int FreeFunction() { return 42; }
+int FreeFunction(int i) {return i;}
+int FreeFunction(int i, int) { return i; }
+int FreeFunction(int i, int, int) { return i; }
+
+#endif // FUNCTION_TYPES_H
diff --git a/test/std/utilities/memory/allocator.traits/allocator.traits.types/is_always_equal.pass.cpp b/test/std/utilities/memory/allocator.traits/allocator.traits.types/is_always_equal.pass.cpp
new file mode 100644
index 0000000..31a0f17
--- /dev/null
+++ b/test/std/utilities/memory/allocator.traits/allocator.traits.types/is_always_equal.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// template <class Alloc>
+// struct allocator_traits
+// {
+// typedef Alloc::is_always_equal
+// | is_empty is_always_equal;
+// ...
+// };
+
+#include <memory>
+#include <type_traits>
+
+template <class T>
+struct A
+{
+ typedef T value_type;
+ typedef std::true_type is_always_equal;
+};
+
+template <class T>
+struct B
+{
+ typedef T value_type;
+};
+
+template <class T>
+struct C
+{
+ typedef T value_type;
+ int not_empty_; // some random member variable
+};
+
+int main()
+{
+ static_assert((std::is_same<std::allocator_traits<A<char> >::is_always_equal, std::true_type>::value), "");
+ static_assert((std::is_same<std::allocator_traits<B<char> >::is_always_equal, std::true_type>::value), "");
+ static_assert((std::is_same<std::allocator_traits<C<char> >::is_always_equal, std::false_type>::value), "");
+
+ static_assert((std::is_same<std::allocator_traits<A<const char> >::is_always_equal, std::true_type>::value), "");
+ static_assert((std::is_same<std::allocator_traits<B<const char> >::is_always_equal, std::true_type>::value), "");
+ static_assert((std::is_same<std::allocator_traits<C<const char> >::is_always_equal, std::false_type>::value), "");
+}
diff --git a/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp b/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
index d0a870e..40c44d9 100644
--- a/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator.members/construct.pass.cpp
@@ -15,6 +15,7 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
#include "count_new.hpp"
int A_constructed = 0;
@@ -34,30 +35,22 @@
int move_only_constructed = 0;
+#if TEST_STD_VER >= 11
class move_only
{
int data;
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(const move_only&);
- move_only& operator=(const move_only&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&);
- move_only& operator=(move_only&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+ move_only(const move_only&) = delete;
+ move_only& operator=(const move_only&)= delete;
public:
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
move_only(move_only&&) {++move_only_constructed;}
move_only& operator=(move_only&&) {return *this;}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
- move_only(std::__rv<move_only>) {++move_only_constructed;}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
move_only() {++move_only_constructed;}
~move_only() {--move_only_constructed;}
};
+#endif // TEST_STD_VER >= 11
int main()
{
@@ -108,6 +101,7 @@
assert(globalMemCounter.checkOutstandingNewEq(0));
assert(A_constructed == 0);
}
+#if TEST_STD_VER >= 11
{
std::allocator<move_only> a;
assert(globalMemCounter.checkOutstandingNewEq(0));
@@ -139,4 +133,5 @@
assert(globalMemCounter.checkOutstandingNewEq(0));
assert(move_only_constructed == 0);
}
+#endif
}
diff --git a/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp b/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp
index db08123..cba3210 100644
--- a/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp
+++ b/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp
@@ -22,6 +22,7 @@
// typedef typename add_lvalue_reference<T>::type reference;
// typedef typename add_lvalue_reference<const T>::type const_reference;
// typedef T value_type;
+// typedef true_type is_always_equal;
//
// template <class U> struct rebind {typedef allocator<U> other;};
// ...
@@ -42,6 +43,10 @@
static_assert((std::is_same<std::allocator<char>::const_reference, const char&>::value), "");
static_assert((std::is_same<std::allocator<char>::rebind<int>::other,
std::allocator<int> >::value), "");
+
+ static_assert((std::is_same<std::allocator< char>::is_always_equal, std::true_type>::value), "");
+ static_assert((std::is_same<std::allocator<const char>::is_always_equal, std::true_type>::value), "");
+
std::allocator<char> a;
std::allocator<char> a2 = a;
a2 = a;
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
index 7de7ecc..f431335 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp
@@ -28,8 +28,19 @@
int B::count_ = 0;
+struct Nasty
+{
+ Nasty() : i_ ( counter_++ ) {}
+ Nasty * operator &() const { return NULL; }
+ int i_;
+ static int counter_;
+};
+
+int Nasty::counter_ = 0;
+
int main()
{
+ {
const int N = 5;
char pool[sizeof(B)*N] = {0};
B* bp = (B*)pool;
@@ -48,4 +59,17 @@
std::uninitialized_copy(b, b+2, bp);
for (int i = 0; i < 2; ++i)
assert(bp[i].data_ == 1);
+ }
+ {
+ const int N = 5;
+ char pool[sizeof(Nasty)*N] = {0};
+ Nasty * p = (Nasty *) pool;
+ Nasty arr[N];
+ std::uninitialized_copy(arr, arr+N, p);
+ for (int i = 0; i < N; ++i) {
+ assert(arr[i].i_ == i);
+ assert( p[i].i_ == i);
+ }
+ }
+
}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
index 79afa4f..3b2007b 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy_n.pass.cpp
@@ -28,8 +28,19 @@
int B::count_ = 0;
+struct Nasty
+{
+ Nasty() : i_ ( counter_++ ) {}
+ Nasty * operator &() const { return NULL; }
+ int i_;
+ static int counter_;
+};
+
+int Nasty::counter_ = 0;
+
int main()
{
+ {
const int N = 5;
char pool[sizeof(B)*N] = {0};
B* bp = (B*)pool;
@@ -48,4 +59,16 @@
std::uninitialized_copy_n(b, 2, bp);
for (int i = 0; i < 2; ++i)
assert(bp[i].data_ == 1);
+ }
+ {
+ const int N = 5;
+ char pool[sizeof(Nasty)*N] = {0};
+ Nasty * p = (Nasty *) pool;
+ Nasty arr[N];
+ std::uninitialized_copy_n(arr, N, p);
+ for (int i = 0; i < N; ++i) {
+ assert(arr[i].i_ == i);
+ assert( p[i].i_ == i);
+ }
+ }
}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
index 8fc6b81..d2b1dfa 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill.n/uninitialized_fill_n.pass.cpp
@@ -27,8 +27,19 @@
int B::count_ = 0;
+struct Nasty
+{
+ Nasty() : i_ ( counter_++ ) {}
+ Nasty * operator &() const { return NULL; }
+ int i_;
+ static int counter_;
+};
+
+int Nasty::counter_ = 0;
+
int main()
{
+ {
const int N = 5;
char pool[sizeof(B)*N] = {0};
B* bp = (B*)pool;
@@ -47,4 +58,18 @@
assert(r == bp + 2);
for (int i = 0; i < 2; ++i)
assert(bp[i].data_ == 1);
+ }
+ {
+ {
+ const int N = 5;
+ char pool[N*sizeof(Nasty)] = {0};
+ Nasty* bp = (Nasty*)pool;
+
+ Nasty::counter_ = 23;
+ std::uninitialized_fill_n(bp, N, Nasty());
+ for (int i = 0; i < N; ++i)
+ assert(bp[i].i_ == 23);
+ }
+
+ }
}
diff --git a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
index c34fdc7..47cabdf 100644
--- a/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
+++ b/test/std/utilities/memory/specialized.algorithms/uninitialized.fill/uninitialized_fill.pass.cpp
@@ -28,8 +28,19 @@
int B::count_ = 0;
+struct Nasty
+{
+ Nasty() : i_ ( counter_++ ) {}
+ Nasty * operator &() const { return NULL; }
+ int i_;
+ static int counter_;
+};
+
+int Nasty::counter_ = 0;
+
int main()
{
+ {
const int N = 5;
char pool[sizeof(B)*N] = {0};
B* bp = (B*)pool;
@@ -47,4 +58,15 @@
std::uninitialized_fill(bp, bp+2, B());
for (int i = 0; i < 2; ++i)
assert(bp[i].data_ == 1);
+ }
+ {
+ const int N = 5;
+ char pool[N*sizeof(Nasty)] = {0};
+ Nasty* bp = (Nasty*)pool;
+
+ Nasty::counter_ = 23;
+ std::uninitialized_fill(bp, bp+N, Nasty());
+ for (int i = 0; i < N; ++i)
+ assert(bp[i].i_ == 23);
+ }
}
diff --git a/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp b/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp
new file mode 100644
index 0000000..27b6205
--- /dev/null
+++ b/test/std/utilities/memory/storage.iterator/raw_storag_iterator.base.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// raw_storage_iterator
+
+#include <memory>
+#include <type_traits>
+#include <cassert>
+
+int A_constructed = 0;
+
+struct A
+{
+ int data_;
+public:
+ explicit A(int i) : data_(i) {++A_constructed;}
+
+ A(const A& a) : data_(a.data_) {++A_constructed;}
+ ~A() {--A_constructed; data_ = 0;}
+
+ bool operator==(int i) const {return data_ == i;}
+};
+
+int main()
+{
+#if __cplusplus >= 201402L
+ typedef std::aligned_storage<3*sizeof(A), std::alignment_of<A>::value>::type
+ Storage;
+ Storage buffer;
+ std::raw_storage_iterator<A*, A> it((A*)&buffer);
+ assert(A_constructed == 0);
+ assert(it.base() == (A*)&buffer);
+ for (int i = 0; i < 3; ++i)
+ {
+ *it++ = A(i+1);
+ A* ap = (A*)&buffer + i;
+ assert(*ap == i+1);
+ assert(A_constructed == i+1);
+ assert(it.base() == ap + 1); // next place to write
+ }
+#endif
+}
diff --git a/test/std/utilities/memory/unique.ptr/deleter.h b/test/std/utilities/memory/unique.ptr/deleter.h
index fb26044..ab13c65 100644
--- a/test/std/utilities/memory/unique.ptr/deleter.h
+++ b/test/std/utilities/memory/unique.ptr/deleter.h
@@ -20,21 +20,19 @@
#include <utility>
#include <cassert>
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 11
+
template <class T>
class Deleter
{
int state_;
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(const Deleter&);
Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
Deleter& operator=(Deleter&& r)
{
@@ -42,22 +40,12 @@
r.state_ = 0;
return *this;
}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
Deleter() : state_(0) {}
explicit Deleter(int s) : state_(s) {}
~Deleter() {assert(state_ >= 0); state_ = -1;}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class U>
Deleter(Deleter<U>&& d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
@@ -67,12 +55,6 @@
template <class U>
Deleter(const Deleter<U>& d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U> d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
public:
int state() const {return state_;}
void set_state(int i) {state_ = i;}
@@ -85,16 +67,11 @@
{
int state_;
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(const Deleter&);
Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
Deleter& operator=(Deleter&& r)
{
@@ -102,16 +79,6 @@
r.state_ = 0;
return *this;
}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter() : state_(0) {}
explicit Deleter(int s) : state_(s) {}
@@ -123,6 +90,69 @@
void operator()(T* p) {delete [] p;}
};
+#else // TEST_STD_VER < 11
+
+template <class T>
+class Deleter
+{
+ mutable int state_;
+
+public:
+ Deleter() : state_(0) {}
+ explicit Deleter(int s) : state_(s) {}
+
+ Deleter(Deleter const & other) : state_(other.state_) {
+ other.state_ = 0;
+ }
+ Deleter& operator=(Deleter const& other) {
+ state_ = other.state_;
+ other.state_ = 0;
+ return *this;
+ }
+
+ ~Deleter() {assert(state_ >= 0); state_ = -1;}
+
+private:
+ template <class U>
+ Deleter(Deleter<U> d,
+ typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
+ : state_(d.state()) {}
+
+public:
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) {delete p;}
+};
+
+template <class T>
+class Deleter<T[]>
+{
+ mutable int state_;
+
+public:
+
+ Deleter(Deleter const& other) : state_(other.state_) {
+ other.state_ = 0;
+ }
+ Deleter& operator=(Deleter const& other) {
+ state_ = other.state_;
+ other.state_ = 0;
+ return *this;
+ }
+
+ Deleter() : state_(0) {}
+ explicit Deleter(int s) : state_(s) {}
+ ~Deleter() {assert(state_ >= 0); state_ = -1;}
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) {delete [] p;}
+};
+
+#endif
+
template <class T>
void
swap(Deleter<T>& x, Deleter<T>& y)
@@ -132,6 +162,7 @@
y = std::move(t);
}
+
template <class T>
class CDeleter
{
@@ -179,4 +210,130 @@
y = std::move(t);
}
+// Non-copyable deleter
+template <class T>
+class NCDeleter
+{
+ int state_;
+ NCDeleter(NCDeleter const&);
+ NCDeleter& operator=(NCDeleter const&);
+public:
+
+ NCDeleter() : state_(0) {}
+ explicit NCDeleter(int s) : state_(s) {}
+ ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) {delete p;}
+};
+
+
+template <class T>
+class NCDeleter<T[]>
+{
+ int state_;
+ NCDeleter(NCDeleter const&);
+ NCDeleter& operator=(NCDeleter const&);
+public:
+
+ NCDeleter() : state_(0) {}
+ explicit NCDeleter(int s) : state_(s) {}
+ ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) {delete [] p;}
+};
+
+
+// Non-copyable deleter
+template <class T>
+class NCConstDeleter
+{
+ int state_;
+ NCConstDeleter(NCConstDeleter const&);
+ NCConstDeleter& operator=(NCConstDeleter const&);
+public:
+
+ NCConstDeleter() : state_(0) {}
+ explicit NCConstDeleter(int s) : state_(s) {}
+ ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) const {delete p;}
+};
+
+
+template <class T>
+class NCConstDeleter<T[]>
+{
+ int state_;
+ NCConstDeleter(NCConstDeleter const&);
+ NCConstDeleter& operator=(NCConstDeleter const&);
+public:
+
+ NCConstDeleter() : state_(0) {}
+ explicit NCConstDeleter(int s) : state_(s) {}
+ ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) const {delete [] p;}
+};
+
+
+// Non-copyable deleter
+template <class T>
+class CopyDeleter
+{
+ int state_;
+public:
+
+ CopyDeleter() : state_(0) {}
+ explicit CopyDeleter(int s) : state_(s) {}
+ ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
+
+ CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
+ CopyDeleter& operator=(CopyDeleter const& other) {
+ state_ = other.state_;
+ return *this;
+ }
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) {delete p;}
+};
+
+
+template <class T>
+class CopyDeleter<T[]>
+{
+ int state_;
+
+public:
+
+ CopyDeleter() : state_(0) {}
+ explicit CopyDeleter(int s) : state_(s) {}
+ ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
+
+ CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
+ CopyDeleter& operator=(CopyDeleter const& other) {
+ state_ = other.state_;
+ return *this;
+ }
+
+ int state() const {return state_;}
+ void set_state(int i) {state_ = i;}
+
+ void operator()(T* p) {delete [] p;}
+};
+
+
#endif // DELETER_H
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/move01.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/move01.fail.cpp
index 17375ed..ed94c1a 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/move01.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/move01.fail.cpp
@@ -14,26 +14,15 @@
// Test unique_ptr move assignment
#include <memory>
-#include <utility>
-#include <cassert>
-// Can't copy from lvalue
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
+#include "test_macros.h"
int main()
{
- {
- std::unique_ptr<A> s(new A);
- std::unique_ptr<A> s2;
- s2 = s;
- }
+ std::unique_ptr<int> s, s2;
+#if TEST_STD_VER >= 11
+ s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+#else
+ s2 = s; // expected-error {{'operator=' is a private member of 'std::__1::unique_ptr}}
+#endif
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
index 95350a6..b6bcad9 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
@@ -15,7 +15,6 @@
// default unique_ptr ctor should require default Deleter ctor
-// USE_VERIFY
#include <memory>
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move01.pass.cpp
index 03747b4..5088a44 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move01.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move01.pass.cpp
@@ -32,22 +32,6 @@
int A::count = 0;
-class NCDeleter
-{
- int state_;
-
- NCDeleter(NCDeleter&);
- NCDeleter& operator=(NCDeleter&);
-public:
-
- NCDeleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) {delete [] p;}
-};
-
int main()
{
{
@@ -71,10 +55,10 @@
}
assert(A::count == 0);
{
- NCDeleter d;
- std::unique_ptr<A[], NCDeleter&> s(new A[3], d);
+ NCDeleter<A[]> d;
+ std::unique_ptr<A[], NCDeleter<A[]>&> s(new A[3], d);
A* p = s.get();
- std::unique_ptr<A[], NCDeleter&> s2 = std::move(s);
+ std::unique_ptr<A[], NCDeleter<A[]>&> s2 = std::move(s);
assert(s2.get() == p);
assert(s.get() == 0);
assert(A::count == 3);
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp
index ef821a9..5720d3b 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/move02.pass.cpp
@@ -31,21 +31,6 @@
int A::count = 0;
-class NCDeleter
-{
- int state_;
-
- NCDeleter(NCDeleter&);
- NCDeleter& operator=(NCDeleter&);
-public:
-
- NCDeleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) {delete [] p;}
-};
std::unique_ptr<A[]>
source1()
@@ -67,14 +52,14 @@
{
}
-std::unique_ptr<A[], NCDeleter&>
+std::unique_ptr<A[], NCDeleter<A[]>&>
source3()
{
- static NCDeleter d;
- return std::unique_ptr<A[], NCDeleter&>(new A[3], d);
+ static NCDeleter<A[]> d;
+ return std::unique_ptr<A[], NCDeleter<A[]>&>(new A[3], d);
}
-void sink3(std::unique_ptr<A[], NCDeleter&> p)
+void sink3(std::unique_ptr<A[], NCDeleter<A[]>&> p)
{
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.fail.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.fail.cpp
index b635d50..9d3f940 100644
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.fail.cpp
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runtime.ctor/pointer_deleter04.fail.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: c++98, c++03
+
// <memory>
// unique_ptr
@@ -16,40 +18,16 @@
// unique_ptr<T, const D&>(pointer, D()) should not compile
#include <memory>
-#include <cassert>
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
class Deleter
{
- int state_;
-
public:
-
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) const {delete [] p;}
+ Deleter() {}
+ void operator()(int* p) const {delete [] p;}
};
int main()
{
- {
- A* p = new A[3];
- assert(A::count == 3);
- std::unique_ptr<A[], const Deleter&> s(p, Deleter());
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
+ int* p = nullptr;
+ std::unique_ptr<int[], const Deleter&> s(p, Deleter()); // expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default.pass.cpp
new file mode 100644
index 0000000..2694538
--- /dev/null
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+//=============================================================================
+// TESTING std::unique_ptr::unique_ptr()
+//
+// Concerns:
+// 1 The default constructor works for any default constructible deleter types.
+// 2 The stored type 'T' is allowed to be incomplete.
+//
+// Plan
+// 1 Default construct unique_ptr's with various deleter types (C-1)
+// 2 Default construct a unique_ptr with a incomplete element_type and
+// various deleter types (C-1,2)
+
+#include <memory>
+#include <cassert>
+
+#include "../../deleter.h"
+
+struct IncompleteT;
+
+void checkNumIncompleteTypeAlive(int i);
+
+template <class Del = std::default_delete<IncompleteT> >
+struct StoresIncomplete {
+ std::unique_ptr<IncompleteT, Del> m_ptr;
+ StoresIncomplete() {}
+ ~StoresIncomplete();
+
+ IncompleteT* get() const { return m_ptr.get(); }
+ Del& get_deleter() { return m_ptr.get_deleter(); }
+};
+
+int main()
+{
+ {
+ std::unique_ptr<int> p;
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<int, NCDeleter<int> > p;
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 0);
+ p.get_deleter().set_state(5);
+ assert(p.get_deleter().state() == 5);
+ }
+ {
+ StoresIncomplete<> s;
+ assert(s.get() == 0);
+ checkNumIncompleteTypeAlive(0);
+ }
+ checkNumIncompleteTypeAlive(0);
+ {
+ StoresIncomplete< Deleter<IncompleteT> > s;
+ assert(s.get() == 0);
+ assert(s.get_deleter().state() == 0);
+ checkNumIncompleteTypeAlive(0);
+ }
+ checkNumIncompleteTypeAlive(0);
+}
+
+struct IncompleteT {
+ static int count;
+ IncompleteT() { ++count; }
+ ~IncompleteT() {--count; }
+};
+
+int IncompleteT::count = 0;
+
+void checkNumIncompleteTypeAlive(int i) {
+ assert(IncompleteT::count == i);
+}
+
+template <class Del>
+StoresIncomplete<Del>::~StoresIncomplete() { }
\ No newline at end of file
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default01.pass.cpp
deleted file mode 100644
index e63db5c..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default01.pass.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr default ctor
-
-#include <memory>
-#include <cassert>
-
-// default unique_ptr ctor should only require default Deleter ctor
-class Deleter
-{
- int state_;
-
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-
-public:
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
-
- void operator()(void*) {}
-};
-
-int main()
-{
- {
- std::unique_ptr<int> p;
- assert(p.get() == 0);
- }
- {
- std::unique_ptr<int, Deleter> p;
- assert(p.get() == 0);
- assert(p.get_deleter().state() == 5);
- }
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default02.pass.cpp
deleted file mode 100644
index e9af7e2..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/default02.pass.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test default unique_ptr ctor
-
-#include <memory>
-#include <cassert>
-
-// default unique_ptr ctor shouldn't require complete type
-
-struct A;
-
-class Deleter
-{
- int state_;
-
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-
-public:
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
-
- void operator()(A* p);
-};
-
-void check(int i);
-
-template <class D = std::default_delete<A> >
-struct B
-{
- std::unique_ptr<A, D> a_;
- B() {}
- ~B();
-
- A* get() const {return a_.get();}
- D& get_deleter() {return a_.get_deleter();}
-};
-
-int main()
-{
- {
- B<> s;
- assert(s.get() == 0);
- }
- check(0);
- {
- B<Deleter> s;
- assert(s.get() == 0);
- assert(s.get_deleter().state() == 5);
- }
- check(0);
-}
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-void Deleter::operator()(A* p) {delete p;}
-
-void check(int i)
-{
- assert(A::count == i);
-}
-
-template <class D>
-B<D>::~B() {}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move.pass.cpp
new file mode 100644
index 0000000..4c5cc84
--- /dev/null
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move.pass.cpp
@@ -0,0 +1,140 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr move ctor
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "../../deleter.h"
+
+//=============================================================================
+// TESTING unique_ptr(unique_ptr&&)
+//
+// Concerns
+// 1 The moved from pointer is empty and the new pointer stores the old value.
+// 2 The only requirement on the deleter is that it is MoveConstructible
+// or a reference.
+// 3 The constructor works for explicitly moved values (ie std::move(x))
+// 4 The constructor works for true temporaries (ie a return value)
+//
+// Plan
+// 1 Explicitly construct unique_ptr<T, D> for various deleter types 'D'.
+// check that the value and deleter have been properly moved. (C-1,2,3)
+//
+// 2 Use the expression 'sink(source())' to move construct a unique_ptr<T, D>
+// from a temporary. 'source' should return the unique_ptr by value and
+// 'sink' should accept the unique_ptr by value. (C-1,2,4)
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+template <class Expect>
+void sinkFunction(Expect)
+{
+}
+
+typedef std::unique_ptr<A> APtrSource1;
+typedef std::unique_ptr<A, Deleter<A> > APtrSource2;
+typedef std::unique_ptr<A, NCDeleter<A>& > APtrSource3;
+
+APtrSource1 source1() {
+ return APtrSource1 (new A);
+}
+
+void sink1(APtrSource1 p) {
+ assert(p.get() != nullptr);
+}
+
+APtrSource2 source2() {
+ return APtrSource2(new A, Deleter<A>(5));
+}
+
+void sink2(APtrSource2 p) {
+ assert(p.get() != nullptr);
+ assert(p.get_deleter().state() == 5);
+}
+
+APtrSource3 source3() {
+ static NCDeleter<A> d(5);
+ return APtrSource3(new A, d);
+}
+
+void sink3(APtrSource3 p) {
+ assert(p.get() != nullptr);
+ assert(p.get_deleter().state() == 5);
+ assert(&p.get_deleter() == &source3().get_deleter());
+}
+
+int main()
+{
+ {
+ typedef std::unique_ptr<A> APtr;
+ APtr s(new A);
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == 1);
+ }
+ assert(A::count == 0);
+ {
+ typedef Deleter<A> MoveDel;
+ typedef std::unique_ptr<A, MoveDel> APtr;
+ MoveDel d(5);
+ APtr s(new A, std::move(d));
+ assert(d.state() == 0);
+ assert(s.get_deleter().state() == 5);
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == 1);
+ assert(s2.get_deleter().state() == 5);
+ assert(s.get_deleter().state() == 0);
+ }
+ assert(A::count == 0);
+ {
+ typedef NCDeleter<A> NonCopyDel;
+ typedef std::unique_ptr<A, NonCopyDel&> APtr;
+
+ NonCopyDel d;
+ APtr s(new A, d);
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == 1);
+ d.set_state(6);
+ assert(s2.get_deleter().state() == d.state());
+ assert(s.get_deleter().state() == d.state());
+ }
+ assert(A::count == 0);
+ {
+ sink1(source1());
+ assert(A::count == 0);
+ sink2(source2());
+ assert(A::count == 0);
+ sink3(source3());
+ assert(A::count == 0);
+ }
+ assert(A::count == 0);
+}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move01.pass.cpp
deleted file mode 100644
index dc16c31..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move01.pass.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-// test move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-template <class T>
-class Deleter
-{
- int state_;
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(const Deleter&);
- Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
- Deleter& operator=(Deleter&& r)
- {
- state_ = r.state_;
- r.state_ = 0;
- return *this;
- }
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- Deleter() : state_(5) {}
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U>&& d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {d.set_state(0);}
-
-private:
- template <class U>
- Deleter(const Deleter<U>& d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U> d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-public:
- int state() const {return state_;}
- void set_state(int i) {state_ = i;}
-
- void operator()(T* p) {delete p;}
-};
-
-class CDeleter
-{
- int state_;
-
- CDeleter(CDeleter&);
- CDeleter& operator=(CDeleter&);
-public:
-
- CDeleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) {delete p;}
-};
-
-int main()
-{
- {
- std::unique_ptr<A> s(new A);
- A* p = s.get();
- std::unique_ptr<A> s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- }
- assert(A::count == 0);
- {
- std::unique_ptr<A, Deleter<A> > s(new A);
- A* p = s.get();
- std::unique_ptr<A, Deleter<A> > s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(s2.get_deleter().state() == 5);
- assert(s.get_deleter().state() == 0);
- }
- assert(A::count == 0);
- {
- CDeleter d;
- std::unique_ptr<A, CDeleter&> s(new A, d);
- A* p = s.get();
- std::unique_ptr<A, CDeleter&> s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- d.set_state(6);
- assert(s2.get_deleter().state() == d.state());
- assert(s.get_deleter().state() == d.state());
- }
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move02.pass.cpp
deleted file mode 100644
index 4b997df..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move02.pass.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr move ctor
-
-#include <memory>
-#include <cassert>
-
-// test move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-template <class T>
-class Deleter
-{
- int state_;
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(const Deleter&);
- Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
- Deleter& operator=(Deleter&& r)
- {
- state_ = r.state_;
- r.state_ = 0;
- return *this;
- }
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- Deleter() : state_(5) {}
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U>&& d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {d.set_state(0);}
-
-private:
- template <class U>
- Deleter(const Deleter<U>& d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U> d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-public:
- int state() const {return state_;}
- void set_state(int i) {state_ = i;}
-
- void operator()(T* p) {delete p;}
-};
-
-class CDeleter
-{
- int state_;
-
- CDeleter(CDeleter&);
- CDeleter& operator=(CDeleter&);
-public:
-
- CDeleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) {delete p;}
-};
-
-std::unique_ptr<A>
-source1()
-{
- return std::unique_ptr<A>(new A);
-}
-
-void sink1(std::unique_ptr<A> p)
-{
-}
-
-std::unique_ptr<A, Deleter<A> >
-source2()
-{
- return std::unique_ptr<A, Deleter<A> >(new A);
-}
-
-void sink2(std::unique_ptr<A, Deleter<A> > p)
-{
-}
-
-std::unique_ptr<A, CDeleter&>
-source3()
-{
- static CDeleter d;
- return std::unique_ptr<A, CDeleter&>(new A, d);
-}
-
-void sink3(std::unique_ptr<A, CDeleter&> p)
-{
-}
-
-int main()
-{
- sink1(source1());
- sink2(source2());
- sink3(source3());
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp
new file mode 100644
index 0000000..7136253
--- /dev/null
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert.pass.cpp
@@ -0,0 +1,175 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr converting move ctor
+
+// NOTE: unique_ptr does not provide converting constructors in c++03
+// XFAIL: c++98, c++03
+
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <cassert>
+
+#include "../../deleter.h"
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+// Explicit version
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+struct B
+ : public A
+{
+ static int count;
+ B() {++count;}
+ B(const B&) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+template <class OrigPtr, class NewPtr>
+void checkDeleter(OrigPtr& O, NewPtr& N, int OrigState, int NewState) {
+ typedef typename NewPtr::deleter_type NewDel;
+ if (std::is_reference<NewDel>::value) {
+ O.get_deleter().set_state(42);
+ assert(O.get_deleter().state() == 42);
+ assert(N.get_deleter().state() == 42);
+ O.get_deleter().set_state(99);
+ assert(O.get_deleter().state() == 99);
+ assert(N.get_deleter().state() == 99);
+ } else {
+ // TODO(EricWF) Enable this?
+ // assert(OrigState != NewState);
+ assert(O.get_deleter().state() == OrigState);
+ assert(N.get_deleter().state() == NewState);
+ }
+}
+
+template <class APtr, class BPtr>
+void testMoveConvertExplicit()
+{
+ { // Test explicit constructor
+ BPtr s(new B);
+ A* p = s.get();
+ APtr s2(std::move(s));
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == 1);
+ assert(B::count == 1);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
+
+template <class APtr, class BPtr>
+void testMoveConvertImplicit() {
+
+ { // Test implicit constructor
+ BPtr s(new B);
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == 1);
+ assert(B::count == 1);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
+
+template <class APtr, class BPtr, class Deleter>
+#if TEST_STD_VER >= 11
+void testMoveConvertExplicit(Deleter&& del) {
+#else
+void testMoveConvert(Deleter& del) {
+#endif
+ int old_val = del.state();
+ { // Test Explicit constructor
+ BPtr s(new B, std::forward<Deleter>(del));
+ A* p = s.get();
+ APtr s2(std::move(s));
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ checkDeleter(s, s2, del.state(), old_val);
+ assert(A::count == 1);
+ assert(B::count == 1);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
+
+
+template <class APtr, class BPtr, class Deleter>
+#if TEST_STD_VER >= 11
+void testMoveConvertImplicit(Deleter&& del) {
+#else
+void testMoveConvertImplicit(Deleter& del) {
+#endif
+ int old_val = del.state();
+ { // Test Implicit constructor
+ BPtr s(new B, std::forward<Deleter>(del));
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ checkDeleter(s, s2, del.state(), old_val);
+ assert(A::count == 1);
+ assert(B::count == 1);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
+int main()
+{
+ {
+ typedef std::unique_ptr<A> APtr;
+ typedef std::unique_ptr<B> BPtr;
+ testMoveConvertExplicit<APtr, BPtr>();
+ testMoveConvertImplicit<APtr, BPtr>();
+ }
+ {
+ typedef std::unique_ptr<A, Deleter<A> > APtr;
+ typedef std::unique_ptr<B, Deleter<B> > BPtr;
+ Deleter<B> del(5);
+ testMoveConvertExplicit<APtr, BPtr>(std::move(del));
+ del.set_state(5);
+ testMoveConvertImplicit<APtr, BPtr>(std::move(del));
+ }
+ {
+ typedef std::unique_ptr<A, NCDeleter<A>& > APtr;
+ typedef std::unique_ptr<B, NCDeleter<A>& > BPtr;
+ NCDeleter<A> del(5);
+ testMoveConvertExplicit<APtr, BPtr>(del);
+ testMoveConvertImplicit<APtr, BPtr>(del);
+ }
+ {
+ typedef std::unique_ptr<A, CDeleter<A> > APtr;
+ typedef std::unique_ptr<B, CDeleter<B>& > BPtr;
+ CDeleter<B> del(5);
+ testMoveConvertImplicit<APtr, BPtr>(del);
+ testMoveConvertExplicit<APtr, BPtr>(del);
+ }
+}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert01.pass.cpp
deleted file mode 100644
index b65cf56..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert01.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// Explicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
- {
- std::unique_ptr<B> s(new B);
- A* p = s.get();
- std::unique_ptr<A> s2(std::move(s));
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert02.pass.cpp
deleted file mode 100644
index 829e755..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert02.pass.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-#include "../../deleter.h"
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// Explicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
- {
- std::unique_ptr<B, Deleter<B> > s(new B, Deleter<B>(5));
- A* p = s.get();
- std::unique_ptr<A, Deleter<A> > s2(std::move(s));
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- assert(s2.get_deleter().state() == 5);
- assert(s.get_deleter().state() == 0);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert03.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert03.pass.cpp
deleted file mode 100644
index 792076a..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert03.pass.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// Explicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-template <class T>
-class CDeleter
-{
- int state_;
-
- CDeleter(CDeleter&);
- CDeleter& operator=(CDeleter&);
-public:
-
- CDeleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(T* p) {delete p;}
-};
-
-int main()
-{
- {
- CDeleter<A> d;
- std::unique_ptr<B, CDeleter<A>&> s(new B, d);
- A* p = s.get();
- std::unique_ptr<A, CDeleter<A>&> s2(std::move(s));
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- d.set_state(6);
- assert(s2.get_deleter().state() == d.state());
- assert(s.get_deleter().state() == d.state());
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert04.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert04.pass.cpp
deleted file mode 100644
index 12ab17f..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert04.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// implicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
- {
- std::unique_ptr<B> s(new B);
- A* p = s.get();
- std::unique_ptr<A> s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert05.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert05.pass.cpp
deleted file mode 100644
index 8077b0d..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert05.pass.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-#include "../../deleter.h"
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// Implicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
- {
- std::unique_ptr<B, Deleter<B> > s(new B, Deleter<B>(5));
- A* p = s.get();
- std::unique_ptr<A, Deleter<A> > s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- assert(s2.get_deleter().state() == 5);
- assert(s.get_deleter().state() == 0);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert06.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert06.pass.cpp
deleted file mode 100644
index 4115107..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert06.pass.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// Explicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-template <class T>
-class CDeleter
-{
- int state_;
-
- CDeleter(CDeleter&);
- CDeleter& operator=(CDeleter&);
-public:
-
- CDeleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(T* p) {delete p;}
-};
-
-int main()
-{
- {
- CDeleter<A> d;
- std::unique_ptr<B, CDeleter<A>&> s(new B, d);
- A* p = s.get();
- std::unique_ptr<A, CDeleter<A>&> s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- d.set_state(6);
- assert(s2.get_deleter().state() == d.state());
- assert(s.get_deleter().state() == d.state());
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert07.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert07.pass.cpp
deleted file mode 100644
index 978cb0e..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/move_convert07.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr converting move ctor
-
-#include <memory>
-#include <utility>
-#include <cassert>
-
-#include "../../deleter.h"
-
-// test converting move ctor. Should only require a MoveConstructible deleter, or if
-// deleter is a reference, not even that.
-// Implicit version
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main()
-{
- {
- CDeleter<B> b(5);
- std::unique_ptr<B, CDeleter<B>&> s(new B, b);
- A* p = s.get();
- std::unique_ptr<A, CDeleter<A> > s2 = std::move(s);
- assert(s2.get() == p);
- assert(s.get() == 0);
- assert(A::count == 1);
- assert(B::count == 1);
- assert(s2.get_deleter().state() == 5);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer.pass.cpp
new file mode 100644
index 0000000..faa554d
--- /dev/null
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer.pass.cpp
@@ -0,0 +1,163 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+//=============================================================================
+// TESTING std::unique_ptr::unique_ptr()
+//
+// Concerns:
+// 1 The pointer constructor works for any default constructible deleter types.
+// 2 The pointer constructor accepts pointers to derived types.
+// 2 The stored type 'T' is allowed to be incomplete.
+//
+// Plan
+// 1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
+// types (C-1)
+// 2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
+// types where 'D' is derived from 'T'. (C-1,2)
+// 3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
+// types where 'T' is an incomplete type (C-1,3)
+
+// Test unique_ptr(pointer) ctor
+
+#include <memory>
+#include <cassert>
+
+#include "../../deleter.h"
+
+// unique_ptr(pointer) ctor should only require default Deleter ctor
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+
+struct B
+ : public A
+{
+ static int count;
+ B() {++count;}
+ B(const B&) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+
+struct IncompleteT;
+
+IncompleteT* getIncomplete();
+void checkNumIncompleteTypeAlive(int i);
+
+template <class Del = std::default_delete<IncompleteT> >
+struct StoresIncomplete {
+ std::unique_ptr<IncompleteT, Del> m_ptr;
+ StoresIncomplete() {}
+ explicit StoresIncomplete(IncompleteT* ptr) : m_ptr(ptr) {}
+ ~StoresIncomplete();
+
+ IncompleteT* get() const { return m_ptr.get(); }
+ Del& get_deleter() { return m_ptr.get_deleter(); }
+};
+
+void test_pointer()
+{
+ {
+ A* p = new A;
+ assert(A::count == 1);
+ std::unique_ptr<A> s(p);
+ assert(s.get() == p);
+ }
+ assert(A::count == 0);
+ {
+ A* p = new A;
+ assert(A::count == 1);
+ std::unique_ptr<A, NCDeleter<A> > s(p);
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 0);
+ }
+ assert(A::count == 0);
+}
+
+void test_derived()
+{
+ {
+ B* p = new B;
+ assert(A::count == 1);
+ assert(B::count == 1);
+ std::unique_ptr<A> s(p);
+ assert(s.get() == p);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+ {
+ B* p = new B;
+ assert(A::count == 1);
+ assert(B::count == 1);
+ std::unique_ptr<A, NCDeleter<A> > s(p);
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 0);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
+
+void test_incomplete()
+{
+ {
+ IncompleteT* p = getIncomplete();
+ checkNumIncompleteTypeAlive(1);
+ StoresIncomplete<> s(p);
+ assert(s.get() == p);
+ }
+ checkNumIncompleteTypeAlive(0);
+ {
+ IncompleteT* p = getIncomplete();
+ checkNumIncompleteTypeAlive(1);
+ StoresIncomplete< NCDeleter<IncompleteT> > s(p);
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 0);
+ }
+ checkNumIncompleteTypeAlive(0);
+}
+
+struct IncompleteT {
+ static int count;
+ IncompleteT() { ++count; }
+ ~IncompleteT() {--count; }
+};
+
+int IncompleteT::count = 0;
+
+IncompleteT* getIncomplete() {
+ return new IncompleteT;
+}
+
+void checkNumIncompleteTypeAlive(int i) {
+ assert(IncompleteT::count == i);
+}
+
+template <class Del>
+StoresIncomplete<Del>::~StoresIncomplete() { }
+
+int main()
+{
+ test_pointer();
+ test_derived();
+ test_incomplete();
+}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer01.pass.cpp
deleted file mode 100644
index e5fff77..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer01.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer) ctor should only require default Deleter ctor
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-class Deleter
-{
- int state_;
-
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-
-public:
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
-
- void operator()(A* p) {delete p;}
-};
-
-int main()
-{
- {
- A* p = new A;
- assert(A::count == 1);
- std::unique_ptr<A> s(p);
- assert(s.get() == p);
- }
- assert(A::count == 0);
- {
- A* p = new A;
- assert(A::count == 1);
- std::unique_ptr<A, Deleter> s(p);
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer02.pass.cpp
deleted file mode 100644
index a226e87..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer02.pass.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer) ctor shouldn't require complete type
-
-struct A;
-
-class Deleter
-{
- int state_;
-
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-
-public:
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
-
- void operator()(A* p);
-};
-
-void check(int i);
-
-template <class D = std::default_delete<A> >
-struct B
-{
- std::unique_ptr<A, D> a_;
- explicit B(A*);
- ~B();
-
- A* get() const {return a_.get();}
- D& get_deleter() {return a_.get_deleter();}
-};
-
-A* get();
-
-int main()
-{
- {
- A* p = get();
- check(1);
- B<> s(p);
- assert(s.get() == p);
- }
- check(0);
- {
- A* p = get();
- check(1);
- B<Deleter> s(p);
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- check(0);
-}
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-A* get() {return new A;}
-
-void Deleter::operator()(A* p) {delete p;}
-
-void check(int i)
-{
- assert(A::count == i);
-}
-
-template <class D>
-B<D>::B(A* a) : a_(a) {}
-
-template <class D>
-B<D>::~B() {}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer03.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer03.pass.cpp
deleted file mode 100644
index 42fc094..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer03.pass.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer) ctor should work with derived pointers
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-class Deleter
-{
- int state_;
-
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-
-public:
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
-
- void operator()(A* p) {delete p;}
-};
-
-int main()
-{
- {
- B* p = new B;
- assert(A::count == 1);
- assert(B::count == 1);
- std::unique_ptr<A> s(p);
- assert(s.get() == p);
- }
- assert(A::count == 0);
- assert(B::count == 0);
- {
- B* p = new B;
- assert(A::count == 1);
- assert(B::count == 1);
- std::unique_ptr<A, Deleter> s(p);
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter.pass.cpp
new file mode 100644
index 0000000..7ddd162
--- /dev/null
+++ b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter.pass.cpp
@@ -0,0 +1,123 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+//=============================================================================
+// TESTING unique_ptr(pointer, deleter)
+//
+// Concerns:
+// 1 unique_ptr(pointer, deleter&&) only requires a MoveConstructible deleter.
+// 2 unique_ptr(pointer, deleter&) requires a CopyConstructible deleter.
+// 3 unique_ptr<T, D&>(pointer, deleter) does not require a CopyConstructible deleter.
+// 4 unique_ptr<T, D const&>(pointer, deleter) does not require a CopyConstructible deleter.
+// 5 unique_ptr(pointer, deleter) should work for derived pointers.
+// 6 unique_ptr(pointer, deleter) should work with function pointers.
+// 7 unique_ptr<void> should work.
+
+
+#include <memory>
+#include <cassert>
+
+#include "../../deleter.h"
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+
+struct B
+ : public A
+{
+ static int count;
+ B() {++count;}
+ B(const B&) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+bool my_free_called = false;
+
+void my_free(void*) {
+ my_free_called = true;
+}
+
+int main()
+{
+ { // MoveConstructible deleter (C-1)
+ A* p = new A;
+ assert(A::count == 1);
+ std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>(5));
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 5);
+ }
+ assert(A::count == 0);
+ { // CopyConstructible deleter (C-2)
+ A* p = new A;
+ assert(A::count == 1);
+ CopyDeleter<A> d(5);
+ std::unique_ptr<A, CopyDeleter<A> > s(p, d);
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 5);
+ d.set_state(6);
+ assert(s.get_deleter().state() == 5);
+ }
+ assert(A::count == 0);
+ { // Reference deleter (C-3)
+ A* p = new A;
+ assert(A::count == 1);
+ NCDeleter<A> d(5);
+ std::unique_ptr<A, NCDeleter<A>&> s(p, d);
+ assert(s.get() == p);
+ assert(&s.get_deleter() == &d);
+ assert(s.get_deleter().state() == 5);
+ d.set_state(6);
+ assert(s.get_deleter().state() == 6);
+ }
+ assert(A::count == 0);
+ { // Const Reference deleter (C-4)
+ A* p = new A;
+ assert(A::count == 1);
+ NCConstDeleter<A> d(5);
+ std::unique_ptr<A, NCConstDeleter<A> const&> s(p, d);
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 5);
+ assert(&s.get_deleter() == &d);
+ }
+ assert(A::count == 0);
+ { // Derived pointers (C-5)
+ B* p = new B;
+ assert(A::count == 1);
+ assert(B::count == 1);
+ std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>(5));
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 5);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+ { // Void and function pointers (C-6,7)
+ {
+ int i = 0;
+ std::unique_ptr<void, void(*)(void*)> s(&i, my_free);
+ assert(s.get() == &i);
+ assert(s.get_deleter() == my_free);
+ assert(!my_free_called);
+ }
+ assert(my_free_called);
+ }
+}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter01.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter01.pass.cpp
deleted file mode 100644
index 130f91d..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter01.pass.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-template <class T>
-class Deleter
-{
- int state_;
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(const Deleter&);
- Deleter& operator=(const Deleter&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&);
- Deleter& operator=(Deleter&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
-public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
- Deleter& operator=(Deleter&& r)
- {
- state_ = r.state_;
- r.state_ = 0;
- return *this;
- }
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
- Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
- Deleter& operator=(std::__rv<Deleter> r)
- {
- state_ = r->state_;
- r->state_ = 0;
- return *this;
- }
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
- Deleter() : state_(5) {}
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U>&& d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {d.set_state(0);}
-
-private:
- template <class U>
- Deleter(const Deleter<U>& d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- template <class U>
- Deleter(Deleter<U> d,
- typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
- : state_(d.state()) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-public:
- int state() const {return state_;}
- void set_state(int i) {state_ = i;}
-
- void operator()(T* p) {delete p;}
-};
-
-int main()
-{
- {
- A* p = new A;
- assert(A::count == 1);
- std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>());
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter02.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter02.pass.cpp
deleted file mode 100644
index 421bec5..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter02.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer, d) requires CopyConstructible deleter
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-class Deleter
-{
- int state_;
-
-public:
-
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) {delete p;}
-};
-
-int main()
-{
- {
- A* p = new A;
- assert(A::count == 1);
- Deleter d;
- std::unique_ptr<A, Deleter> s(p, d);
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- d.set_state(6);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter03.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter03.pass.cpp
deleted file mode 100644
index bce79db..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter03.pass.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-class Deleter
-{
- int state_;
-
- Deleter(const Deleter&);
- Deleter& operator=(const Deleter&);
-public:
-
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) {delete p;}
-};
-
-int main()
-{
- {
- A* p = new A;
- assert(A::count == 1);
- Deleter d;
- std::unique_ptr<A, Deleter&> s(p, d);
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- d.set_state(6);
- assert(s.get_deleter().state() == 6);
- }
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.pass.cpp
deleted file mode 100644
index a7750fc..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter04.pass.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- ~A() {--count;}
-};
-
-int A::count = 0;
-
-class Deleter
-{
- int state_;
-
- Deleter(const Deleter&);
- Deleter& operator=(const Deleter&);
-public:
-
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
- void set_state(int s) {state_ = s;}
-
- void operator()(A* p) const {delete p;}
-};
-
-int main()
-{
- {
- A* p = new A;
- assert(A::count == 1);
- Deleter d;
- std::unique_ptr<A, const Deleter&> s(p, d);
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter05.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter05.pass.cpp
deleted file mode 100644
index 1a83258..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter05.pass.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer, deleter) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer, deleter) should work with derived pointers
-
-struct A
-{
- static int count;
- A() {++count;}
- A(const A&) {++count;}
- virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
- : public A
-{
- static int count;
- B() {++count;}
- B(const B&) {++count;}
- virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-class Deleter
-{
- int state_;
-
-public:
- Deleter() : state_(5) {}
-
- int state() const {return state_;}
-
- void operator()(A* p) {delete p;}
-};
-
-int main()
-{
- {
- B* p = new B;
- assert(A::count == 1);
- assert(B::count == 1);
- std::unique_ptr<A, Deleter> s(p, Deleter());
- assert(s.get() == p);
- assert(s.get_deleter().state() == 5);
- }
- assert(A::count == 0);
- assert(B::count == 0);
-}
diff --git a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter06.pass.cpp b/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter06.pass.cpp
deleted file mode 100644
index ed68052..0000000
--- a/test/std/utilities/memory/unique.ptr/unique.ptr.single/unique.ptr.single.ctor/pointer_deleter06.pass.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// Test unique_ptr(pointer, deleter) ctor
-
-#include <memory>
-#include <cassert>
-
-// unique_ptr(pointer, deleter) should work with function pointers
-// unique_ptr<void> should work
-
-bool my_free_called = false;
-
-void my_free(void*)
-{
- my_free_called = true;
-}
-
-int main()
-{
- {
- int i = 0;
- std::unique_ptr<void, void (*)(void*)> s(&i, my_free);
- assert(s.get() == &i);
- assert(s.get_deleter() == my_free);
- assert(!my_free_called);
- }
- assert(my_free_called);
-}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
index 58686d6..77af13f 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.enab/enable_shared_from_this.pass.cpp
@@ -34,6 +34,10 @@
int main()
{
+ { // https://llvm.org/bugs/show_bug.cgi?id=18843
+ std::shared_ptr<T const> t1(new T);
+ std::shared_ptr<T const> t2(std::make_shared<T>());
+ }
{
std::shared_ptr<Y> p(new Z);
std::shared_ptr<T> q = p->shared_from_this();
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/unique_ptr_Y.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/unique_ptr_Y.pass.cpp
index 742d8c1..30e0fce 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/unique_ptr_Y.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/unique_ptr_Y.pass.cpp
@@ -67,7 +67,7 @@
pB = std::move(pA);
assert(B::count == 0);
assert(A::count == 0);
- assert(pB.use_count() == 1);
+// assert(pB.use_count() == 1); // no longer true due to LWG 2415
assert(pA.get() == 0);
assert(pB.get() == ptrA);
}
@@ -101,7 +101,7 @@
pB = std::move(pA);
assert(B::count == 0);
assert(A::count == 0);
- assert(pB.use_count() == 1);
+// assert(pB.use_count() == 1); // no longer true due to LWG 2415
assert(pA.get() == 0);
assert(pB.get() == ptrA);
}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp
index 28e49d6..b2e61fa 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp
@@ -11,7 +11,7 @@
// template<class Y> explicit shared_ptr(auto_ptr<Y>&& r);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <memory>
#include <new>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
index a8588cc..97d3f69 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_throw.pass.cpp
@@ -13,7 +13,7 @@
// template<class D> shared_ptr(nullptr_t, D d);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <memory>
#include <cassert>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
index b024f7e..ead0816 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_throw.pass.cpp
@@ -13,7 +13,7 @@
// template<class Y, class D> shared_ptr(Y* p, D d);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <memory>
#include <cassert>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
index 28fb8bf..041fe9a 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_throw.pass.cpp
@@ -11,7 +11,7 @@
// template<class Y> explicit shared_ptr(Y* p);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <memory>
#include <new>
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
index dc2a6af..5e09d9a 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp
@@ -11,7 +11,7 @@
// template <class Y, class D> explicit shared_ptr(unique_ptr<Y, D>&&r);
-// UNSUPPORTED: asan, msan
+// UNSUPPORTED: sanitizer-new-delete
#include <memory>
#include <new>
@@ -58,6 +58,9 @@
void fn ( const std::shared_ptr<int> &) {}
void fn ( const std::shared_ptr<B> &) { assert (false); }
+template <typename T>
+void assert_deleter ( T * ) { assert(false); }
+
int main()
{
{
@@ -100,4 +103,13 @@
throw_next = false;
fn(std::unique_ptr<int>(new int));
}
+
+#if __cplusplus >= 201402L
+ // LWG 2415
+ {
+ std::unique_ptr<int, void (*)(int*)> p(nullptr, assert_deleter<int>);
+ std::shared_ptr<int> p2(std::move(p)); // should not call deleter when going out of scope
+ }
+#endif
+
}
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
index 5dfa4cd..8cb972b 100644
--- a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp
@@ -37,6 +37,14 @@
int A::count = 0;
+
+struct Foo
+{
+ Foo() = default;
+ virtual ~Foo() = default;
+};
+
+
int main()
{
int nc = globalMemCounter.outstanding_new;
@@ -49,6 +57,14 @@
assert(p->get_int() == 67);
assert(p->get_char() == 'e');
}
+
+ { // https://llvm.org/bugs/show_bug.cgi?id=24137
+ std::shared_ptr<Foo> p1 = std::make_shared<Foo>();
+ assert(p1.get());
+ std::shared_ptr<const Foo> p2 = std::make_shared<const Foo>();
+ assert(p2.get());
+ }
+
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
nc = globalMemCounter.outstanding_new;
{
diff --git a/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp
new file mode 100644
index 0000000..1045f93
--- /dev/null
+++ b/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// shared_ptr
+
+// template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
+
+#include <memory>
+#include <cassert>
+
+template <typename T>
+void test(const T &t0)
+{
+ {
+ T t1 = t0;
+ std::shared_ptr<T> p0 = std::make_shared<T>(t0);
+ std::shared_ptr<T> p1 = std::make_shared<T>(t1);
+ assert(*p0 == t0);
+ assert(*p1 == t1);
+ }
+
+ {
+ const T t1 = t0;
+ std::shared_ptr<const T> p0 = std::make_shared<const T>(t0);
+ std::shared_ptr<const T> p1 = std::make_shared<const T>(t1);
+ assert(*p0 == t0);
+ assert(*p1 == t1);
+ }
+
+ {
+ volatile T t1 = t0;
+ std::shared_ptr<volatile T> p0 = std::make_shared<volatile T>(t0);
+ std::shared_ptr<volatile T> p1 = std::make_shared<volatile T>(t1);
+ assert(*p0 == t0);
+ assert(*p1 == t1);
+ }
+
+ {
+ const volatile T t1 = t0;
+ std::shared_ptr<const volatile T> p0 = std::make_shared<const volatile T>(t0);
+ std::shared_ptr<const volatile T> p1 = std::make_shared<const volatile T>(t1);
+ assert(*p0 == t0);
+ assert(*p1 == t1);
+ }
+
+}
+
+int main()
+{
+ test<bool>(true);
+ test<int>(3);
+ test<double>(5.0);
+}
diff --git a/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp b/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp
new file mode 100644
index 0000000..71110ea
--- /dev/null
+++ b/test/std/utilities/meta/meta.hel/bool_constant.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// bool_constant
+
+#include <type_traits>
+#include <cassert>
+
+int main()
+{
+#if __cplusplus > 201402L
+ typedef std::bool_constant<true> _t;
+ static_assert(_t::value, "");
+ static_assert((std::is_same<_t::value_type, bool>::value), "");
+ static_assert((std::is_same<_t::type, _t>::value), "");
+ static_assert((_t() == true), "");
+
+ typedef std::bool_constant<false> _f;
+ static_assert(!_f::value, "");
+ static_assert((std::is_same<_f::value_type, bool>::value), "");
+ static_assert((std::is_same<_f::type, _f>::value), "");
+ static_assert((_f() == false), "");
+#endif
+}
diff --git a/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp b/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp
index 718e0ff..429fb33 100644
--- a/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp
+++ b/test/std/utilities/meta/meta.rel/is_convertible.pass.cpp
@@ -186,4 +186,10 @@
static_assert((std::is_convertible<volatile NonCopyable&, const volatile NonCopyable&>::value), "");
static_assert((std::is_convertible<const volatile NonCopyable&, const volatile NonCopyable&>::value), "");
static_assert((!std::is_convertible<const NonCopyable&, NonCopyable&>::value), "");
+// This test requires Access control SFINAE which we only have in C++11 or when
+// we are using the compiler builtin for is_convertible.
+#if __cplusplus >= 201103L || !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK)
+ test_is_not_convertible<NonCopyable&, NonCopyable>();
+#endif
+
}
diff --git a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp b/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp
similarity index 69%
copy from test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
copy to test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp
index b58f5c5..bd35ef6 100644
--- a/test/std/strings/basic.string/string.require/nothing_to_do.pass.cpp
+++ b/test/std/utilities/meta/meta.rel/is_convertible_fallback.pass.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
-int main()
-{
-}
+// type_traits
+
+// is_convertible
+
+// Test the fallback implementation.
+
+#define _LIBCPP_USE_IS_CONVERTIBLE_FALLBACK
+#include "is_convertible.pass.cpp"
+
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
index 1064d59..5a925bb 100644
--- a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
@@ -13,83 +13,240 @@
#include <type_traits>
#include <memory>
-
-typedef bool (&PF1)();
-typedef short (*PF2)(long);
+#include "test_macros.h"
struct S
{
- operator PF2() const;
+ typedef short (*FreeFunc)(long);
+ operator FreeFunc() const;
double operator()(char, int&);
- void calc(long) const;
- char data_;
+ double const& operator()(char, int&) const;
+ double volatile& operator()(char, int&) volatile;
+ double const volatile& operator()(char, int&) const volatile;
};
-typedef void (S::*PMS)(long) const;
-typedef char S::*PMD;
-
-struct wat
-{
- wat& operator*() { return *this; }
- void foo();
+template <class Tp>
+struct Voider {
+ typedef void type;
};
-struct F {};
+template <class T, class = void>
+struct HasType : std::false_type {};
+
+template <class T>
+struct HasType<T, typename Voider<typename T::type>::type> : std::true_type {};
template <class T, class U>
-void test_result_of_imp()
+void test_result_of()
{
static_assert((std::is_same<typename std::result_of<T>::type, U>::value), "");
-#if _LIBCPP_STD_VER > 11
- static_assert((std::is_same<std::result_of_t<T>, U>::value), "");
+}
+
+template <class T>
+void test_no_result()
+{
+#if TEST_STD_VER >= 11
+ static_assert((!HasType<std::result_of<T> >::value), "");
#endif
}
int main()
{
- test_result_of_imp<S(int), short> ();
- test_result_of_imp<S&(unsigned char, int&), double> ();
- test_result_of_imp<PF1(), bool> ();
- test_result_of_imp<PMS(std::unique_ptr<S>, int), void> ();
- test_result_of_imp<PMS(S, int), void> ();
- test_result_of_imp<PMS(const S&, int), void> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- test_result_of_imp<PMD(S), char&&> ();
-#endif
- test_result_of_imp<PMD(const S*), const char&> ();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- test_result_of_imp<int (F::* (F &)) () &, int> ();
- test_result_of_imp<int (F::* (F &)) () const &, int> ();
- test_result_of_imp<int (F::* (F const &)) () const &, int> ();
- test_result_of_imp<int (F::* (F &&)) () &&, int> ();
- test_result_of_imp<int (F::* (F &&)) () const&&, int> ();
- test_result_of_imp<int (F::* (F const&&)) () const&&, int> ();
-#endif
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
- using type1 = std::result_of<decltype(&wat::foo)(wat)>::type;
- static_assert(std::is_same<type1, void>::value, "");
-#endif
-#if _LIBCPP_STD_VER > 11
- using type2 = std::result_of_t<decltype(&wat::foo)(wat)>;
- static_assert(std::is_same<type2, void>::value, "");
-#endif
+ { // functor object
+ test_result_of<S(int), short> ();
+ test_result_of<S&(unsigned char, int&), double> ();
+ test_result_of<S const&(unsigned char, int&), double const &> ();
+ test_result_of<S volatile&(unsigned char, int&), double volatile&> ();
+ test_result_of<S const volatile&(unsigned char, int&), double const volatile&> ();
+ }
+ { // pointer to function
+ typedef bool (&RF0)();
+ typedef bool* (&RF1)(int);
+ typedef bool& (&RF2)(int, int);
+ typedef bool const& (&RF3)(int, int, int);
+ typedef bool (*PF0)();
+ typedef bool* (*PF1)(int);
+ typedef bool& (*PF2)(int, int);
+ typedef bool const& (*PF3)(int, int, int);
+ typedef bool (*&PRF0)();
+ typedef bool* (*&PRF1)(int);
+ typedef bool& (*&PRF2)(int, int);
+ typedef bool const& (*&PRF3)(int, int, int);
+ test_result_of<RF0(), bool>();
+ test_result_of<RF1(int), bool*>();
+ test_result_of<RF2(int, long), bool&>();
+ test_result_of<RF3(int, long, int), bool const&>();
+ test_result_of<PF0(), bool>();
+ test_result_of<PF1(int), bool*>();
+ test_result_of<PF2(int, long), bool&>();
+ test_result_of<PF3(int, long, int), bool const&>();
+ test_result_of<PRF0(), bool>();
+ test_result_of<PRF1(int), bool*>();
+ test_result_of<PRF2(int, long), bool&>();
+ test_result_of<PRF3(int, long, int), bool const&>();
+ }
+ { // pointer to member function
- static_assert((std::is_same<std::result_of<S(int)>::type, short>::value), "Error!");
- static_assert((std::is_same<std::result_of<S&(unsigned char, int&)>::type, double>::value), "Error!");
- static_assert((std::is_same<std::result_of<PF1()>::type, bool>::value), "Error!");
- static_assert((std::is_same<std::result_of<PMS(std::unique_ptr<S>, int)>::type, void>::value), "Error!");
- static_assert((std::is_same<std::result_of<PMS(S, int)>::type, void>::value), "Error!");
- static_assert((std::is_same<std::result_of<PMS(const S&, int)>::type, void>::value), "Error!");
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- static_assert((std::is_same<std::result_of<PMD(S)>::type, char&&>::value), "Error!");
-#endif
- static_assert((std::is_same<std::result_of<PMD(const S*)>::type, const char&>::value), "Error!");
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- static_assert((std::is_same<std::result_of<int (F::* (F &)) () &>::type, int>::value), "Error!");
- static_assert((std::is_same<std::result_of<int (F::* (F &)) () const &>::type, int>::value), "Error!");
- static_assert((std::is_same<std::result_of<int (F::* (F const &)) () const &>::type, int>::value), "Error!");
- static_assert((std::is_same<std::result_of<int (F::* (F &&)) () &&>::type, int>::value), "Error!");
- static_assert((std::is_same<std::result_of<int (F::* (F &&)) () const&&>::type, int>::value), "Error!");
- static_assert((std::is_same<std::result_of<int (F::* (F const&&)) () const&&>::type, int>::value), "Error!");
-#endif
+ typedef int (S::*PMS0)();
+ typedef int* (S::*PMS1)(long);
+ typedef int& (S::*PMS2)(long, int);
+ test_result_of<PMS0( S), int> ();
+ test_result_of<PMS0( S&), int> ();
+ test_result_of<PMS0( S*), int> ();
+ test_result_of<PMS0( S*&), int> ();
+ test_result_of<PMS0(std::unique_ptr<S>), int> ();
+ test_no_result<PMS0(const S&)>();
+ test_no_result<PMS0(volatile S&)>();
+ test_no_result<PMS0(const volatile S&)>();
+
+ test_result_of<PMS1( S, int), int*> ();
+ test_result_of<PMS1( S&, int), int*> ();
+ test_result_of<PMS1( S*, int), int*> ();
+ test_result_of<PMS1( S*&, int), int*> ();
+ test_result_of<PMS1(std::unique_ptr<S>, int), int*> ();
+ test_no_result<PMS1(const S&, int)>();
+ test_no_result<PMS1(volatile S&, int)>();
+ test_no_result<PMS1(const volatile S&, int)>();
+
+ test_result_of<PMS2( S, int, int), int&> ();
+ test_result_of<PMS2( S&, int, int), int&> ();
+ test_result_of<PMS2( S*, int, int), int&> ();
+ test_result_of<PMS2( S*&, int, int), int&> ();
+ test_result_of<PMS2(std::unique_ptr<S>, int, int), int&> ();
+ test_no_result<PMS2(const S&, int, int)>();
+ test_no_result<PMS2(volatile S&, int, int)>();
+ test_no_result<PMS2(const volatile S&, int, int)>();
+
+ typedef int (S::*PMS0C)() const;
+ typedef int* (S::*PMS1C)(long) const;
+ typedef int& (S::*PMS2C)(long, int) const;
+ test_result_of<PMS0C( S), int> ();
+ test_result_of<PMS0C( S&), int> ();
+ test_result_of<PMS0C(const S&), int> ();
+ test_result_of<PMS0C( S*), int> ();
+ test_result_of<PMS0C(const S*), int> ();
+ test_result_of<PMS0C( S*&), int> ();
+ test_result_of<PMS0C(const S*&), int> ();
+ test_result_of<PMS0C(std::unique_ptr<S>), int> ();
+ test_no_result<PMS0C(volatile S&)>();
+ test_no_result<PMS0C(const volatile S&)>();
+
+ test_result_of<PMS1C( S, int), int*> ();
+ test_result_of<PMS1C( S&, int), int*> ();
+ test_result_of<PMS1C(const S&, int), int*> ();
+ test_result_of<PMS1C( S*, int), int*> ();
+ test_result_of<PMS1C(const S*, int), int*> ();
+ test_result_of<PMS1C( S*&, int), int*> ();
+ test_result_of<PMS1C(const S*&, int), int*> ();
+ test_result_of<PMS1C(std::unique_ptr<S>, int), int*> ();
+ test_no_result<PMS1C(volatile S&, int)>();
+ test_no_result<PMS1C(const volatile S&, int)>();
+
+ test_result_of<PMS2C( S, int, int), int&> ();
+ test_result_of<PMS2C( S&, int, int), int&> ();
+ test_result_of<PMS2C(const S&, int, int), int&> ();
+ test_result_of<PMS2C( S*, int, int), int&> ();
+ test_result_of<PMS2C(const S*, int, int), int&> ();
+ test_result_of<PMS2C( S*&, int, int), int&> ();
+ test_result_of<PMS2C(const S*&, int, int), int&> ();
+ test_result_of<PMS2C(std::unique_ptr<S>, int, int), int&> ();
+ test_no_result<PMS2C(volatile S&, int, int)>();
+ test_no_result<PMS2C(const volatile S&, int, int)>();
+
+ typedef int (S::*PMS0V)() volatile;
+ typedef int* (S::*PMS1V)(long) volatile;
+ typedef int& (S::*PMS2V)(long, int) volatile;
+ test_result_of<PMS0V( S), int> ();
+ test_result_of<PMS0V( S&), int> ();
+ test_result_of<PMS0V(volatile S&), int> ();
+ test_result_of<PMS0V( S*), int> ();
+ test_result_of<PMS0V(volatile S*), int> ();
+ test_result_of<PMS0V( S*&), int> ();
+ test_result_of<PMS0V(volatile S*&), int> ();
+ test_result_of<PMS0V(std::unique_ptr<S>), int> ();
+ test_no_result<PMS0V(const S&)>();
+ test_no_result<PMS0V(const volatile S&)>();
+
+ test_result_of<PMS1V( S, int), int*> ();
+ test_result_of<PMS1V( S&, int), int*> ();
+ test_result_of<PMS1V(volatile S&, int), int*> ();
+ test_result_of<PMS1V( S*, int), int*> ();
+ test_result_of<PMS1V(volatile S*, int), int*> ();
+ test_result_of<PMS1V( S*&, int), int*> ();
+ test_result_of<PMS1V(volatile S*&, int), int*> ();
+ test_result_of<PMS1V(std::unique_ptr<S>, int), int*> ();
+ test_no_result<PMS1V(const S&, int)>();
+ test_no_result<PMS1V(const volatile S&, int)>();
+
+ test_result_of<PMS2V( S, int, int), int&> ();
+ test_result_of<PMS2V( S&, int, int), int&> ();
+ test_result_of<PMS2V(volatile S&, int, int), int&> ();
+ test_result_of<PMS2V( S*, int, int), int&> ();
+ test_result_of<PMS2V(volatile S*, int, int), int&> ();
+ test_result_of<PMS2V( S*&, int, int), int&> ();
+ test_result_of<PMS2V(volatile S*&, int, int), int&> ();
+ test_result_of<PMS2V(std::unique_ptr<S>, int, int), int&> ();
+ test_no_result<PMS2V(const S&, int, int)>();
+ test_no_result<PMS2V(const volatile S&, int, int)>();
+
+ typedef int (S::*PMS0CV)() const volatile;
+ typedef int* (S::*PMS1CV)(long) const volatile;
+ typedef int& (S::*PMS2CV)(long, int) const volatile;
+ test_result_of<PMS0CV( S), int> ();
+ test_result_of<PMS0CV( S&), int> ();
+ test_result_of<PMS0CV(const S&), int> ();
+ test_result_of<PMS0CV(volatile S&), int> ();
+ test_result_of<PMS0CV(const volatile S&), int> ();
+ test_result_of<PMS0CV( S*), int> ();
+ test_result_of<PMS0CV(const S*), int> ();
+ test_result_of<PMS0CV(volatile S*), int> ();
+ test_result_of<PMS0CV(const volatile S*), int> ();
+ test_result_of<PMS0CV( S*&), int> ();
+ test_result_of<PMS0CV(const S*&), int> ();
+ test_result_of<PMS0CV(volatile S*&), int> ();
+ test_result_of<PMS0CV(const volatile S*&), int> ();
+ test_result_of<PMS0CV(std::unique_ptr<S>), int> ();
+
+ test_result_of<PMS1CV( S, int), int*> ();
+ test_result_of<PMS1CV( S&, int), int*> ();
+ test_result_of<PMS1CV(const S&, int), int*> ();
+ test_result_of<PMS1CV(volatile S&, int), int*> ();
+ test_result_of<PMS1CV(const volatile S&, int), int*> ();
+ test_result_of<PMS1CV( S*, int), int*> ();
+ test_result_of<PMS1CV(const S*, int), int*> ();
+ test_result_of<PMS1CV(volatile S*, int), int*> ();
+ test_result_of<PMS1CV(const volatile S*, int), int*> ();
+ test_result_of<PMS1CV( S*&, int), int*> ();
+ test_result_of<PMS1CV(const S*&, int), int*> ();
+ test_result_of<PMS1CV(volatile S*&, int), int*> ();
+ test_result_of<PMS1CV(const volatile S*&, int), int*> ();
+ test_result_of<PMS1CV(std::unique_ptr<S>, int), int*> ();
+
+ test_result_of<PMS2CV( S, int, int), int&> ();
+ test_result_of<PMS2CV( S&, int, int), int&> ();
+ test_result_of<PMS2CV(const S&, int, int), int&> ();
+ test_result_of<PMS2CV(volatile S&, int, int), int&> ();
+ test_result_of<PMS2CV(const volatile S&, int, int), int&> ();
+ test_result_of<PMS2CV( S*, int, int), int&> ();
+ test_result_of<PMS2CV(const S*, int, int), int&> ();
+ test_result_of<PMS2CV(volatile S*, int, int), int&> ();
+ test_result_of<PMS2CV(const volatile S*, int, int), int&> ();
+ test_result_of<PMS2CV( S*&, int, int), int&> ();
+ test_result_of<PMS2CV(const S*&, int, int), int&> ();
+ test_result_of<PMS2CV(volatile S*&, int, int), int&> ();
+ test_result_of<PMS2CV(const volatile S*&, int, int), int&> ();
+ test_result_of<PMS2CV(std::unique_ptr<S>, int, int), int&> ();
+ }
+ { // pointer to member data
+ typedef char S::*PMD;
+ test_result_of<PMD(S&), char &>();
+ test_result_of<PMD(S*), char &>();
+ test_result_of<PMD(S* const), char &>();
+ test_result_of<PMD(const S&), const char&> ();
+ test_result_of<PMD(const S*), const char&> ();
+ test_result_of<PMD(volatile S&), volatile char&> ();
+ test_result_of<PMD(volatile S*), volatile char&> ();
+ test_result_of<PMD(const volatile S&), const volatile char&> ();
+ test_result_of<PMD(const volatile S*), const volatile char&> ();
+ }
}
diff --git a/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp
new file mode 100644
index 0000000..6996cdd
--- /dev/null
+++ b/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: c++98, c++03
+//
+// <functional>
+//
+// result_of<Fn(ArgTypes...)>
+
+#include <type_traits>
+#include "test_macros.h"
+
+struct wat
+{
+ wat& operator*() { return *this; }
+ void foo();
+};
+
+struct F {};
+
+template <class T, class U>
+void test_result_of_imp()
+{
+ static_assert((std::is_same<typename std::result_of<T>::type, U>::value), "");
+#if TEST_STD_VER > 11
+ static_assert((std::is_same<std::result_of_t<T>, U>::value), "");
+#endif
+}
+
+int main()
+{
+ {
+ typedef char F::*PMD;
+ test_result_of_imp<PMD(F &), char &>();
+ test_result_of_imp<PMD(F const &), char const &>();
+ test_result_of_imp<PMD(F volatile &), char volatile &>();
+ test_result_of_imp<PMD(F const volatile &), char const volatile &>();
+
+ test_result_of_imp<PMD(F &&), char &&>();
+ test_result_of_imp<PMD(F const &&), char const &&>();
+ test_result_of_imp<PMD(F volatile &&), char volatile &&>();
+ test_result_of_imp<PMD(F const volatile &&), char const volatile &&>();
+
+ test_result_of_imp<PMD(F ), char &&>();
+ test_result_of_imp<PMD(F const ), char &&>();
+ test_result_of_imp<PMD(F volatile ), char &&>();
+ test_result_of_imp<PMD(F const volatile ), char &&>();
+ }
+ {
+ test_result_of_imp<int (F::* (F &)) () &, int> ();
+ test_result_of_imp<int (F::* (F &)) () const &, int> ();
+ test_result_of_imp<int (F::* (F &)) () volatile &, int> ();
+ test_result_of_imp<int (F::* (F &)) () const volatile &, int> ();
+ test_result_of_imp<int (F::* (F const &)) () const &, int> ();
+ test_result_of_imp<int (F::* (F const &)) () const volatile &, int> ();
+ test_result_of_imp<int (F::* (F volatile &)) () volatile &, int> ();
+ test_result_of_imp<int (F::* (F volatile &)) () const volatile &, int> ();
+ test_result_of_imp<int (F::* (F const volatile &)) () const volatile &, int> ();
+
+ test_result_of_imp<int (F::* (F &&)) () &&, int> ();
+ test_result_of_imp<int (F::* (F &&)) () const &&, int> ();
+ test_result_of_imp<int (F::* (F &&)) () volatile &&, int> ();
+ test_result_of_imp<int (F::* (F &&)) () const volatile &&, int> ();
+ test_result_of_imp<int (F::* (F const &&)) () const &&, int> ();
+ test_result_of_imp<int (F::* (F const &&)) () const volatile &&, int> ();
+ test_result_of_imp<int (F::* (F volatile &&)) () volatile &&, int> ();
+ test_result_of_imp<int (F::* (F volatile &&)) () const volatile &&, int> ();
+ test_result_of_imp<int (F::* (F const volatile &&)) () const volatile &&, int> ();
+
+ test_result_of_imp<int (F::* (F )) () &&, int> ();
+ test_result_of_imp<int (F::* (F )) () const &&, int> ();
+ test_result_of_imp<int (F::* (F )) () volatile &&, int> ();
+ test_result_of_imp<int (F::* (F )) () const volatile &&, int> ();
+ test_result_of_imp<int (F::* (F const )) () const &&, int> ();
+ test_result_of_imp<int (F::* (F const )) () const volatile &&, int> ();
+ test_result_of_imp<int (F::* (F volatile )) () volatile &&, int> ();
+ test_result_of_imp<int (F::* (F volatile )) () const volatile &&, int> ();
+ test_result_of_imp<int (F::* (F const volatile )) () const volatile &&, int> ();
+ }
+
+ test_result_of_imp<decltype(&wat::foo)(wat), void>();
+}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp
index 67ef3db..6f546ef 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.cat/member_function_pointer.pass.cpp
@@ -12,12 +12,13 @@
// member_function_pointer
#include <type_traits>
+#include "test_macros.h"
template <class T>
void test_member_function_pointer_imp()
{
static_assert(!std::is_void<T>::value, "");
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
static_assert(!std::is_null_pointer<T>::value, "");
#endif
static_assert(!std::is_integral<T>::value, "");
@@ -73,30 +74,63 @@
test_member_function_pointer<void (Class::*)(int, ...) volatile>();
test_member_function_pointer<void (Class::*)(int, char, ...) volatile>();
-#if __cplusplus >= 201103L
// reference qualifiers on functions are a C++11 extension
- test_member_function_pointer<void (Class::*)() &&>();
- test_member_function_pointer<void (Class::*)(int) &&>();
- test_member_function_pointer<void (Class::*)(int, char) &&>();
-
+#if TEST_STD_VER >= 11
test_member_function_pointer<void (Class::*)() &>();
test_member_function_pointer<void (Class::*)(int) &>();
test_member_function_pointer<void (Class::*)(int, char) &>();
-
- test_member_function_pointer<void (Class::*)() volatile &&>();
- test_member_function_pointer<void (Class::*)(int) volatile &&>();
- test_member_function_pointer<void (Class::*)(int, char) volatile &&>();
-
- test_member_function_pointer<void (Class::*)(...) &&>();
- test_member_function_pointer<void (Class::*)(int,...) &&>();
- test_member_function_pointer<void (Class::*)(int, char,...) &&>();
-
test_member_function_pointer<void (Class::*)(...) &>();
test_member_function_pointer<void (Class::*)(int,...) &>();
test_member_function_pointer<void (Class::*)(int, char,...) &>();
+ test_member_function_pointer<void (Class::*)() const &>();
+ test_member_function_pointer<void (Class::*)(int) const &>();
+ test_member_function_pointer<void (Class::*)(int, char) const &>();
+ test_member_function_pointer<void (Class::*)(...) const &>();
+ test_member_function_pointer<void (Class::*)(int,...) const &>();
+ test_member_function_pointer<void (Class::*)(int, char,...) const &>();
+
+ test_member_function_pointer<void (Class::*)() volatile &>();
+ test_member_function_pointer<void (Class::*)(int) volatile &>();
+ test_member_function_pointer<void (Class::*)(int, char) volatile &>();
+ test_member_function_pointer<void (Class::*)(...) volatile &>();
+ test_member_function_pointer<void (Class::*)(int,...) volatile &>();
+ test_member_function_pointer<void (Class::*)(int, char,...) volatile &>();
+
+ test_member_function_pointer<void (Class::*)() const volatile &>();
+ test_member_function_pointer<void (Class::*)(int) const volatile &>();
+ test_member_function_pointer<void (Class::*)(int, char) const volatile &>();
+ test_member_function_pointer<void (Class::*)(...) const volatile &>();
+ test_member_function_pointer<void (Class::*)(int,...) const volatile &>();
+ test_member_function_pointer<void (Class::*)(int, char,...) const volatile &>();
+
+ // RValue qualifiers
+ test_member_function_pointer<void (Class::*)() &&>();
+ test_member_function_pointer<void (Class::*)(int) &&>();
+ test_member_function_pointer<void (Class::*)(int, char) &&>();
+ test_member_function_pointer<void (Class::*)(...) &&>();
+ test_member_function_pointer<void (Class::*)(int,...) &&>();
+ test_member_function_pointer<void (Class::*)(int, char,...) &&>();
+
+ test_member_function_pointer<void (Class::*)() const &&>();
+ test_member_function_pointer<void (Class::*)(int) const &&>();
+ test_member_function_pointer<void (Class::*)(int, char) const &&>();
+ test_member_function_pointer<void (Class::*)(...) const &&>();
+ test_member_function_pointer<void (Class::*)(int,...) const &&>();
+ test_member_function_pointer<void (Class::*)(int, char,...) const &&>();
+
+ test_member_function_pointer<void (Class::*)() volatile &&>();
+ test_member_function_pointer<void (Class::*)(int) volatile &&>();
+ test_member_function_pointer<void (Class::*)(int, char) volatile &&>();
test_member_function_pointer<void (Class::*)(...) volatile &&>();
test_member_function_pointer<void (Class::*)(int,...) volatile &&>();
test_member_function_pointer<void (Class::*)(int, char,...) volatile &&>();
+
+ test_member_function_pointer<void (Class::*)() const volatile &&>();
+ test_member_function_pointer<void (Class::*)(int) const volatile &&>();
+ test_member_function_pointer<void (Class::*)(int, char) const volatile &&>();
+ test_member_function_pointer<void (Class::*)(...) const volatile &&>();
+ test_member_function_pointer<void (Class::*)(int,...) const volatile &&>();
+ test_member_function_pointer<void (Class::*)(int, char,...) const volatile &&>();
#endif
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp
index b46a4d6..d33019b 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_assignable.pass.cpp
@@ -49,6 +49,9 @@
};
#endif
+template <typename T>
+struct X { T t; };
+
int main()
{
test_is_assignable<int&, int&> ();
@@ -67,4 +70,7 @@
test_is_not_assignable<void, const void> ();
test_is_not_assignable<const void, const void> ();
test_is_not_assignable<int(), int> ();
+
+// pointer to incomplete template type
+ test_is_assignable<X<D>*&, X<D>*> ();
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp
index 807745e..fae9557 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_destructible.pass.cpp
@@ -13,6 +13,8 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T>
void test_is_destructible()
{
@@ -68,6 +70,7 @@
struct PureProtectedDestructor { protected: virtual ~PureProtectedDestructor() = 0; };
struct PurePrivateDestructor { private: virtual ~PurePrivateDestructor() = 0; };
+#if TEST_STD_VER >= 11
struct DeletedPublicDestructor { public: ~DeletedPublicDestructor() = delete; };
struct DeletedProtectedDestructor { protected: ~DeletedProtectedDestructor() = delete; };
struct DeletedPrivateDestructor { private: ~DeletedPrivateDestructor() = delete; };
@@ -75,6 +78,7 @@
struct DeletedVirtualPublicDestructor { public: virtual ~DeletedVirtualPublicDestructor() = delete; };
struct DeletedVirtualProtectedDestructor { protected: virtual ~DeletedVirtualProtectedDestructor() = delete; };
struct DeletedVirtualPrivateDestructor { private: virtual ~DeletedVirtualPrivateDestructor() = delete; };
+#endif
int main()
@@ -99,23 +103,27 @@
test_is_not_destructible<int[]>();
test_is_not_destructible<void>();
+ test_is_not_destructible<Function>();
+#if TEST_STD_VER >= 11
+ // Test access controlled destructors
test_is_not_destructible<ProtectedDestructor>();
test_is_not_destructible<PrivateDestructor>();
test_is_not_destructible<VirtualProtectedDestructor>();
test_is_not_destructible<VirtualPrivateDestructor>();
test_is_not_destructible<PureProtectedDestructor>();
test_is_not_destructible<PurePrivateDestructor>();
+
+ // Test deleted constructors
test_is_not_destructible<DeletedPublicDestructor>();
test_is_not_destructible<DeletedProtectedDestructor>();
test_is_not_destructible<DeletedPrivateDestructor>();
-
-// test_is_not_destructible<DeletedVirtualPublicDestructor>(); // currently fails due to clang bug #20268
+ //test_is_not_destructible<DeletedVirtualPublicDestructor>(); // previously failed due to clang bug #20268
test_is_not_destructible<DeletedVirtualProtectedDestructor>();
test_is_not_destructible<DeletedVirtualPrivateDestructor>();
-#if __has_feature(cxx_access_control_sfinae)
+ // Test private destructors
test_is_not_destructible<NotEmpty>();
#endif
- test_is_not_destructible<Function>();
+
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
index 8fd5bab..5827c92 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_destructible.pass.cpp
@@ -13,6 +13,8 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T>
void test_is_nothrow_destructible()
{
@@ -31,14 +33,23 @@
static_assert(!std::is_nothrow_destructible<const volatile T>::value, "");
}
+
+struct PublicDestructor { public: ~PublicDestructor() {}};
+struct ProtectedDestructor { protected: ~ProtectedDestructor() {}};
+struct PrivateDestructor { private: ~PrivateDestructor() {}};
+
+struct VirtualPublicDestructor { public: virtual ~VirtualPublicDestructor() {}};
+struct VirtualProtectedDestructor { protected: virtual ~VirtualProtectedDestructor() {}};
+struct VirtualPrivateDestructor { private: virtual ~VirtualPrivateDestructor() {}};
+
+struct PurePublicDestructor { public: virtual ~PurePublicDestructor() = 0; };
+struct PureProtectedDestructor { protected: virtual ~PureProtectedDestructor() = 0; };
+struct PurePrivateDestructor { private: virtual ~PurePrivateDestructor() = 0; };
+
class Empty
{
};
-class NotEmpty
-{
- virtual ~NotEmpty();
-};
union Union {};
@@ -52,40 +63,36 @@
virtual void foo() = 0;
};
-class AbstractDestructor
-{
- virtual ~AbstractDestructor() = 0;
-};
-
-struct A
-{
- ~A();
-};
int main()
{
test_is_not_nothrow_destructible<void>();
- test_is_not_nothrow_destructible<AbstractDestructor>();
- test_is_not_nothrow_destructible<NotEmpty>();
test_is_not_nothrow_destructible<char[]>();
+ test_is_not_nothrow_destructible<char[][3]>();
-#if __has_feature(cxx_noexcept)
- test_is_nothrow_destructible<A>();
-#endif
test_is_nothrow_destructible<int&>();
-#if __has_feature(cxx_unrestricted_unions)
- test_is_nothrow_destructible<Union>();
-#endif
-#if __has_feature(cxx_access_control_sfinae)
- test_is_nothrow_destructible<Empty>();
-#endif
test_is_nothrow_destructible<int>();
test_is_nothrow_destructible<double>();
test_is_nothrow_destructible<int*>();
test_is_nothrow_destructible<const int*>();
test_is_nothrow_destructible<char[3]>();
- test_is_nothrow_destructible<Abstract>();
-#if __has_feature(cxx_noexcept)
+
+#if TEST_STD_VER >= 11
+ // requires noexcept. These are all destructible.
+ test_is_nothrow_destructible<PublicDestructor>();
+ test_is_nothrow_destructible<VirtualPublicDestructor>();
+ test_is_nothrow_destructible<PurePublicDestructor>();
test_is_nothrow_destructible<bit_zero>();
+ test_is_nothrow_destructible<Abstract>();
+ test_is_nothrow_destructible<Empty>();
+ test_is_nothrow_destructible<Union>();
+
+ // requires access control
+ test_is_not_nothrow_destructible<ProtectedDestructor>();
+ test_is_not_nothrow_destructible<PrivateDestructor>();
+ test_is_not_nothrow_destructible<VirtualProtectedDestructor>();
+ test_is_not_nothrow_destructible<VirtualPrivateDestructor>();
+ test_is_not_nothrow_destructible<PureProtectedDestructor>();
+ test_is_not_nothrow_destructible<PurePrivateDestructor>();
#endif
}
diff --git a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp
index b18ace4..0908f8b 100644
--- a/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp
+++ b/test/std/utilities/meta/meta.unary/meta.unary.prop/is_trivially_destructible.pass.cpp
@@ -13,6 +13,8 @@
#include <type_traits>
+#include "test_macros.h"
+
template <class T>
void test_is_trivially_destructible()
{
@@ -31,15 +33,23 @@
static_assert(!std::is_trivially_destructible<const volatile T>::value, "");
}
+struct PublicDestructor { public: ~PublicDestructor() {}};
+struct ProtectedDestructor { protected: ~ProtectedDestructor() {}};
+struct PrivateDestructor { private: ~PrivateDestructor() {}};
+
+struct VirtualPublicDestructor { public: virtual ~VirtualPublicDestructor() {}};
+struct VirtualProtectedDestructor { protected: virtual ~VirtualProtectedDestructor() {}};
+struct VirtualPrivateDestructor { private: virtual ~VirtualPrivateDestructor() {}};
+
+struct PurePublicDestructor { public: virtual ~PurePublicDestructor() = 0; };
+struct PureProtectedDestructor { protected: virtual ~PureProtectedDestructor() = 0; };
+struct PurePrivateDestructor { private: virtual ~PurePrivateDestructor() = 0; };
+
+
class Empty
{
};
-class NotEmpty
-{
- virtual ~NotEmpty();
-};
-
union Union {};
struct bit_zero
@@ -66,18 +76,28 @@
{
test_is_not_trivially_destructible<void>();
test_is_not_trivially_destructible<A>();
- test_is_not_trivially_destructible<AbstractDestructor>();
- test_is_not_trivially_destructible<NotEmpty>();
test_is_not_trivially_destructible<char[]>();
+ test_is_not_trivially_destructible<VirtualPublicDestructor>();
+ test_is_not_trivially_destructible<PurePublicDestructor>();
test_is_trivially_destructible<Abstract>();
- test_is_trivially_destructible<int&>();
test_is_trivially_destructible<Union>();
test_is_trivially_destructible<Empty>();
+ test_is_trivially_destructible<int&>();
test_is_trivially_destructible<int>();
test_is_trivially_destructible<double>();
test_is_trivially_destructible<int*>();
test_is_trivially_destructible<const int*>();
test_is_trivially_destructible<char[3]>();
test_is_trivially_destructible<bit_zero>();
+
+#if TEST_STD_VER >= 11
+ // requires access control sfinae
+ test_is_not_trivially_destructible<ProtectedDestructor>();
+ test_is_not_trivially_destructible<PrivateDestructor>();
+ test_is_not_trivially_destructible<VirtualProtectedDestructor>();
+ test_is_not_trivially_destructible<VirtualPrivateDestructor>();
+ test_is_not_trivially_destructible<PureProtectedDestructor>();
+ test_is_not_trivially_destructible<PurePrivateDestructor>();
+#endif
}
diff --git a/test/std/utilities/ratio/ratio.ratio/ratio.pass.cpp b/test/std/utilities/ratio/ratio.ratio/ratio.pass.cpp
index f942c96..a732616 100644
--- a/test/std/utilities/ratio/ratio.ratio/ratio.pass.cpp
+++ b/test/std/utilities/ratio/ratio.ratio/ratio.pass.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-// test ratio: The static data members num and den shall have thcommon
+// test ratio: The static data members num and den shall have the common
// divisor of the absolute values of N and D:
#include <ratio>
diff --git a/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
index 7fe78ba..df5ec4a 100644
--- a/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
@@ -14,6 +14,8 @@
#include <bitset>
#include <cassert>
+#include <algorithm> // for 'min' and 'max'
+#include <stdexcept> // for 'invalid_argument'
#pragma clang diagnostic ignored "-Wtautological-compare"
diff --git a/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
index bcee50c..98083f8 100644
--- a/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
@@ -11,6 +11,8 @@
#include <bitset>
#include <cassert>
+#include <algorithm> // for 'min' and 'max'
+#include <stdexcept> // for 'invalid_argument'
#pragma clang diagnostic ignored "-Wtautological-compare"
diff --git a/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp b/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
index 023fedc..f232447 100644
--- a/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
+++ b/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
@@ -11,6 +11,7 @@
#include <bitset>
#include <cassert>
+#include <algorithm> // for 'min' and 'max'
#pragma clang diagnostic ignored "-Wtautological-compare"
diff --git a/test/std/utilities/utility/declval/declval.pass.cpp b/test/std/utilities/utility/declval/declval.pass.cpp
index 81f4df8..aabd0e6 100644
--- a/test/std/utilities/utility/declval/declval.pass.cpp
+++ b/test/std/utilities/utility/declval/declval.pass.cpp
@@ -14,6 +14,8 @@
#include <utility>
#include <type_traits>
+#include "test_macros.h"
+
class A
{
A(const A&);
@@ -22,9 +24,9 @@
int main()
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
static_assert((std::is_same<decltype(std::declval<A>()), A&&>::value), "");
#else
- static_assert((std::is_same<decltype(std::declval<A>()), A>::value), "");
+ static_assert((std::is_same<decltype(std::declval<A>()), A&>::value), "");
#endif
}
diff --git a/test/std/utilities/utility/forward/move_copy.pass.cpp b/test/std/utilities/utility/forward/move_copy.pass.cpp
index 461a876..fa15553 100644
--- a/test/std/utilities/utility/forward/move_copy.pass.cpp
+++ b/test/std/utilities/utility/forward/move_copy.pass.cpp
@@ -9,6 +9,8 @@
// test move
+// UNSUPPORTED: c++98, c++03
+
#include <utility>
#include <cassert>
@@ -17,25 +19,13 @@
class A
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-#else
-#endif
-
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
A(const A&) {++copy_ctor;}
A& operator=(const A&);
A(A&&) {++move_ctor;}
A& operator=(A&&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- A(const A&) {++copy_ctor;}
- A& operator=(A&);
-
- operator std::__rv<A> () {return std::__rv<A>(*this);}
- A(std::__rv<A>) {++move_ctor;}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
A() {}
};
diff --git a/test/std/utilities/utility/forward/move_if_noexcept.pass.cpp b/test/std/utilities/utility/forward/move_if_noexcept.pass.cpp
index f94ff2a..bc60d3d 100644
--- a/test/std/utilities/utility/forward/move_if_noexcept.pass.cpp
+++ b/test/std/utilities/utility/forward/move_if_noexcept.pass.cpp
@@ -20,6 +20,8 @@
#include <utility>
+#include "test_macros.h"
+
class A
{
A(const A&);
@@ -27,7 +29,7 @@
public:
A() {}
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
A(A&&) {}
#endif
};
@@ -47,20 +49,24 @@
A a;
const A ca;
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if TEST_STD_VER >= 11
static_assert((std::is_same<decltype(std::move_if_noexcept(i)), int&&>::value), "");
static_assert((std::is_same<decltype(std::move_if_noexcept(ci)), const int&&>::value), "");
static_assert((std::is_same<decltype(std::move_if_noexcept(a)), A&&>::value), "");
static_assert((std::is_same<decltype(std::move_if_noexcept(ca)), const A&&>::value), "");
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- static_assert((std::is_same<decltype(std::move_if_noexcept(i)), const int>::value), "");
- static_assert((std::is_same<decltype(std::move_if_noexcept(ci)), const int>::value), "");
- static_assert((std::is_same<decltype(std::move_if_noexcept(a)), const A>::value), "");
- static_assert((std::is_same<decltype(std::move_if_noexcept(ca)), const A>::value), "");
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
static_assert((std::is_same<decltype(std::move_if_noexcept(l)), const legacy&>::value), "");
+#else // C++ < 11
+ // In C++03 libc++ #define's decltype to be __decltype on clang and
+ // __typeof__ for other compilers. __typeof__ does not deduce the reference
+ // qualifiers and will cause this test to fail.
+ static_assert((std::is_same<decltype(std::move_if_noexcept(i)), const int&>::value), "");
+ static_assert((std::is_same<decltype(std::move_if_noexcept(ci)), const int&>::value), "");
+ static_assert((std::is_same<decltype(std::move_if_noexcept(a)), const A&>::value), "");
+ static_assert((std::is_same<decltype(std::move_if_noexcept(ca)), const A&>::value), "");
+ static_assert((std::is_same<decltype(std::move_if_noexcept(l)), const legacy&>::value), "");
+#endif
-#if _LIBCPP_STD_VER > 11
+#if TEST_STD_VER > 11
constexpr int i1 = 23;
constexpr int i2 = std::move_if_noexcept(i1);
static_assert(i2 == 23, "" );
diff --git a/test/std/utilities/utility/forward/move_only.pass.cpp b/test/std/utilities/utility/forward/move_only.pass.cpp
index 0588c11..520bf5e 100644
--- a/test/std/utilities/utility/forward/move_only.pass.cpp
+++ b/test/std/utilities/utility/forward/move_only.pass.cpp
@@ -9,28 +9,18 @@
// test move
+// UNSUPPORTED: c++98, c++03
+
#include <utility>
#include <cassert>
class move_only
{
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
move_only(const move_only&);
move_only& operator=(const move_only&);
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- move_only(move_only&);
- move_only& operator=(move_only&);
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
public:
-
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
move_only(move_only&&) {}
move_only& operator=(move_only&&) {return *this;}
-#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
- operator std::__rv<move_only> () {return std::__rv<move_only>(*this);}
- move_only(std::__rv<move_only>) {}
-#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
move_only() {}
};
diff --git a/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
index 9a303ba..5ac838b 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/tuple_element.pass.cpp
@@ -15,16 +15,41 @@
#include <utility>
-int main()
+template <class T1, class T2>
+void test()
{
{
- typedef std::pair<int, short> P1;
- static_assert((std::is_same<std::tuple_element<0, P1>::type, int>::value), "");
- static_assert((std::is_same<std::tuple_element<1, P1>::type, short>::value), "");
+ typedef T1 Exp1;
+ typedef T2 Exp2;
+ typedef std::pair<T1, T2> P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
}
{
- typedef std::pair<int*, char> P1;
- static_assert((std::is_same<std::tuple_element<0, P1>::type, int*>::value), "");
- static_assert((std::is_same<std::tuple_element<1, P1>::type, char>::value), "");
+ typedef T1 const Exp1;
+ typedef T2 const Exp2;
+ typedef std::pair<T1, T2> const P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
}
+ {
+ typedef T1 volatile Exp1;
+ typedef T2 volatile Exp2;
+ typedef std::pair<T1, T2> volatile P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
+ }
+ {
+ typedef T1 const volatile Exp1;
+ typedef T2 const volatile Exp2;
+ typedef std::pair<T1, T2> const volatile P;
+ static_assert((std::is_same<typename std::tuple_element<0, P>::type, Exp1>::value), "");
+ static_assert((std::is_same<typename std::tuple_element<1, P>::type, Exp2>::value), "");
+ }
+}
+
+int main()
+{
+ test<int, short>();
+ test<int*, char>();
}
diff --git a/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp b/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
index 2be694e..3756e96 100644
--- a/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
+++ b/test/std/utilities/utility/pairs/pair.astuple/tuple_size.pass.cpp
@@ -21,4 +21,16 @@
typedef std::pair<int, short> P1;
static_assert((std::tuple_size<P1>::value == 2), "");
}
+ {
+ typedef std::pair<int, short> const P1;
+ static_assert((std::tuple_size<P1>::value == 2), "");
+ }
+ {
+ typedef std::pair<int, short> volatile P1;
+ static_assert((std::tuple_size<P1>::value == 2), "");
+ }
+ {
+ typedef std::pair<int, short> const volatile P1;
+ static_assert((std::tuple_size<P1>::value == 2), "");
+ }
}
diff --git a/test/support/allocators.h b/test/support/allocators.h
index 5372c07..b7aba12 100644
--- a/test/support/allocators.h
+++ b/test/support/allocators.h
@@ -13,6 +13,8 @@
#include <type_traits>
#include <utility>
+#include "test_macros.h"
+
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class T>
@@ -20,7 +22,7 @@
{
int id_;
public:
- explicit A1(int id = 0) : id_(id) {}
+ explicit A1(int id = 0) TEST_NOEXCEPT : id_(id) {}
typedef T value_type;
@@ -31,13 +33,13 @@
static bool allocate_called;
static std::pair<T*, std::size_t> deallocate_called;
- A1(const A1& a) : id_(a.id()) {copy_called = true;}
- A1(A1&& a) : id_(a.id()) {move_called = true;}
+ A1(const A1& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ A1(A1&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
template <class U>
- A1(const A1<U>& a) : id_(a.id()) {copy_called = true;}
+ A1(const A1<U>& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
template <class U>
- A1(A1<U>&& a) : id_(a.id()) {move_called = true;}
+ A1(A1<U>&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
T* allocate(std::size_t n)
{
@@ -77,7 +79,7 @@
{
int id_;
public:
- explicit A2(int id = 0) : id_(id) {}
+ explicit A2(int id = 0) TEST_NOEXCEPT : id_(id) {}
typedef T value_type;
@@ -92,8 +94,8 @@
static bool move_called;
static bool allocate_called;
- A2(const A2& a) : id_(a.id()) {copy_called = true;}
- A2(A2&& a) : id_(a.id()) {move_called = true;}
+ A2(const A2& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ A2(A2&& a) TEST_NOEXCEPT : id_(a.id()) {move_called = true;}
T* allocate(std::size_t n, const void* hint)
{
@@ -125,7 +127,7 @@
{
int id_;
public:
- explicit A3(int id = 0) : id_(id) {}
+ explicit A3(int id = 0) TEST_NOEXCEPT : id_(id) {}
typedef T value_type;
@@ -139,8 +141,8 @@
static bool constructed;
static bool destroy_called;
- A3(const A3& a) : id_(a.id()) {copy_called = true;}
- A3(A3&& a) : id_(a.id()) {move_called = true;}
+ A3(const A3& a) TEST_NOEXCEPT : id_(a.id()) {copy_called = true;}
+ A3(A3&& a) TEST_NOEXCEPT: id_(a.id()) {move_called = true;}
template <class U, class ...Args>
void construct(U* p, Args&& ...args)
diff --git a/test/support/any_helpers.h b/test/support/any_helpers.h
new file mode 100644
index 0000000..76b1922
--- /dev/null
+++ b/test/support/any_helpers.h
@@ -0,0 +1,318 @@
+#ifndef ANY_HELPERS_H
+#define ANY_HELPERS_H
+
+#include <experimental/any>
+#include <typeinfo>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if !defined(TEST_HAS_NO_RTTI)
+#define RTTI_ASSERT(X) assert(X)
+#else
+#define RTTI_ASSERT(X)
+#endif
+
+template <class _Tp>
+ struct IsSmallObject
+ : public std::integral_constant<bool
+ , sizeof(_Tp) <= (sizeof(void*)*3)
+ && std::alignment_of<void*>::value
+ % std::alignment_of<_Tp>::value == 0
+ && std::is_nothrow_move_constructible<_Tp>::value
+ >
+ {};
+
+
+// Return 'true' if 'Type' will be considered a small type by 'any'
+template <class Type>
+bool isSmallType() {
+#if defined(_LIBCPP_VERSION)
+ return std::experimental::__any_imp::_IsSmallObject<Type>::value;
+#else
+ return IsSmallObject<Type>::value;
+#endif
+
+}
+
+// Assert that an object is empty. If the object used to contain an object
+// of type 'LastType' check that it can no longer be accessed.
+template <class LastType = int>
+void assertEmpty(std::experimental::any const& a) {
+ assert(a.empty());
+ RTTI_ASSERT(a.type() == typeid(void));
+ assert(std::experimental::any_cast<LastType const>(&a) == nullptr);
+}
+
+// Assert that an 'any' object stores the specified 'Type' and 'value'.
+template <class Type>
+void assertContains(std::experimental::any const& a, int value = 1) {
+ assert(!a.empty());
+ RTTI_ASSERT(a.type() == typeid(Type));
+ assert(std::experimental::any_cast<Type const &>(a).value == value);
+}
+
+// Modify the value of a "test type" stored within an any to the specified
+// 'value'.
+template <class Type>
+void modifyValue(std::experimental::any& a, int value) {
+ assert(!a.empty());
+ RTTI_ASSERT(a.type() == typeid(Type));
+ std::experimental::any_cast<Type&>(a).value = value;
+}
+
+// A test type that will trigger the small object optimization within 'any'.
+template <int Dummy = 0>
+struct small_type
+{
+ static int count;
+ static int copied;
+ static int moved;
+ static int const_copied;
+ static int non_const_copied;
+
+ static void reset() {
+ small_type::copied = 0;
+ small_type::moved = 0;
+ small_type::const_copied = 0;
+ small_type::non_const_copied = 0;
+ }
+
+ int value;
+
+ explicit small_type(int val) : value(val) {
+ ++count;
+ }
+
+ small_type(small_type const & other) throw() {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++const_copied;
+ }
+
+ small_type(small_type& other) throw() {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++non_const_copied;
+ }
+
+ small_type(small_type && other) throw() {
+ value = other.value;
+ other.value = 0;
+ ++count;
+ ++moved;
+ }
+
+ ~small_type() {
+ value = -1;
+ --count;
+ }
+
+private:
+ small_type& operator=(small_type const&) = delete;
+ small_type& operator=(small_type&&) = delete;
+};
+
+template <int Dummy>
+int small_type<Dummy>::count = 0;
+
+template <int Dummy>
+int small_type<Dummy>::copied = 0;
+
+template <int Dummy>
+int small_type<Dummy>::moved = 0;
+
+template <int Dummy>
+int small_type<Dummy>::const_copied = 0;
+
+template <int Dummy>
+int small_type<Dummy>::non_const_copied = 0;
+
+typedef small_type<> small;
+typedef small_type<1> small1;
+typedef small_type<2> small2;
+
+
+// A test type that will NOT trigger the small object optimization in any.
+template <int Dummy = 0>
+struct large_type
+{
+ static int count;
+ static int copied;
+ static int moved;
+ static int const_copied;
+ static int non_const_copied;
+
+ static void reset() {
+ large_type::copied = 0;
+ large_type::moved = 0;
+ large_type::const_copied = 0;
+ large_type::non_const_copied = 0;
+ }
+
+ int value;
+
+ large_type(int val) : value(val) {
+ ++count;
+ data[0] = 0;
+ }
+
+ large_type(large_type const & other) {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++const_copied;
+ }
+
+ large_type(large_type & other) {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++non_const_copied;
+ }
+
+ large_type(large_type && other) {
+ value = other.value;
+ other.value = 0;
+ ++count;
+ ++moved;
+ }
+
+ ~large_type() {
+ value = 0;
+ --count;
+ }
+
+private:
+ large_type& operator=(large_type const&) = delete;
+ large_type& operator=(large_type &&) = delete;
+ int data[10];
+};
+
+template <int Dummy>
+int large_type<Dummy>::count = 0;
+
+template <int Dummy>
+int large_type<Dummy>::copied = 0;
+
+template <int Dummy>
+int large_type<Dummy>::moved = 0;
+
+template <int Dummy>
+int large_type<Dummy>::const_copied = 0;
+
+template <int Dummy>
+int large_type<Dummy>::non_const_copied = 0;
+
+typedef large_type<> large;
+typedef large_type<1> large1;
+typedef large_type<2> large2;
+
+// The exception type thrown by 'small_throws_on_copy', 'large_throws_on_copy'
+// and 'throws_on_move'.
+struct my_any_exception {};
+
+void throwMyAnyExpression() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ throw my_any_exception();
+#else
+ assert(false && "Exceptions are disabled");
+#endif
+}
+
+// A test type that will trigger the small object optimization within 'any'.
+// this type throws if it is copied.
+struct small_throws_on_copy
+{
+ static int count;
+ int value;
+
+ explicit small_throws_on_copy(int val = 0) : value(val) {
+ ++count;
+ }
+
+ small_throws_on_copy(small_throws_on_copy const &) {
+ throwMyAnyExpression();
+ }
+
+ small_throws_on_copy(small_throws_on_copy && other) throw() {
+ value = other.value;
+ ++count;
+ }
+
+ ~small_throws_on_copy() {
+ --count;
+ }
+private:
+ small_throws_on_copy& operator=(small_throws_on_copy const&) = delete;
+ small_throws_on_copy& operator=(small_throws_on_copy &&) = delete;
+};
+
+int small_throws_on_copy::count = 0;
+
+// A test type that will NOT trigger the small object optimization within 'any'.
+// this type throws if it is copied.
+struct large_throws_on_copy
+{
+ static int count;
+ int value = 0;
+
+ explicit large_throws_on_copy(int val = 0) : value(val) {
+ data[0] = 0;
+ ++count;
+ }
+
+ large_throws_on_copy(large_throws_on_copy const &) {
+ throwMyAnyExpression();
+ }
+
+ large_throws_on_copy(large_throws_on_copy && other) throw() {
+ value = other.value;
+ ++count;
+ }
+
+ ~large_throws_on_copy() {
+ --count;
+ }
+
+private:
+ large_throws_on_copy& operator=(large_throws_on_copy const&) = delete;
+ large_throws_on_copy& operator=(large_throws_on_copy &&) = delete;
+ int data[10];
+};
+
+int large_throws_on_copy::count = 0;
+
+// A test type that throws when it is moved. This object will NOT trigger
+// the small object optimization in 'any'.
+struct throws_on_move
+{
+ static int count;
+ int value;
+
+ explicit throws_on_move(int val = 0) : value(val) { ++count; }
+
+ throws_on_move(throws_on_move const & other) {
+ value = other.value;
+ ++count;
+ }
+
+ throws_on_move(throws_on_move &&) {
+ throwMyAnyExpression();
+ }
+
+ ~throws_on_move() {
+ --count;
+ }
+private:
+ throws_on_move& operator=(throws_on_move const&) = delete;
+ throws_on_move& operator=(throws_on_move &&) = delete;
+};
+
+int throws_on_move::count = 0;
+
+
+#endif
diff --git a/test/support/count_new.hpp b/test/support/count_new.hpp
index 00df7a1..57aca7d 100644
--- a/test/support/count_new.hpp
+++ b/test/support/count_new.hpp
@@ -10,7 +10,8 @@
#endif
#if __has_feature(address_sanitizer) \
- || __has_feature(memory_sanitizer)
+ || __has_feature(memory_sanitizer) \
+ || __has_feature(thread_sanitizer)
#define DISABLE_NEW_COUNT
#endif
@@ -29,6 +30,10 @@
// All checks return true when disable_checking is enabled.
static const bool disable_checking;
+ // Disallow any allocations from occurring. Useful for testing that
+ // code doesn't perform any allocations.
+ bool disable_allocations;
+
int outstanding_new;
int new_called;
int delete_called;
@@ -42,6 +47,7 @@
public:
void newCalled(std::size_t s)
{
+ assert(disable_allocations == false);
assert(s);
++new_called;
++outstanding_new;
@@ -57,6 +63,7 @@
void newArrayCalled(std::size_t s)
{
+ assert(disable_allocations == false);
assert(s);
++outstanding_array_new;
++new_array_called;
@@ -70,8 +77,20 @@
++delete_array_called;
}
+ void disableAllocations()
+ {
+ disable_allocations = true;
+ }
+
+ void enableAllocations()
+ {
+ disable_allocations = false;
+ }
+
void reset()
{
+ disable_allocations = false;
+
outstanding_new = 0;
new_called = 0;
delete_called = 0;
@@ -202,4 +221,29 @@
#endif // DISABLE_NEW_COUNT
+
+struct DisableAllocationGuard {
+ explicit DisableAllocationGuard(bool disable = true) : m_disabled(disable)
+ {
+ // Don't re-disable if already disabled.
+ if (globalMemCounter.disable_allocations == true) m_disabled = false;
+ if (m_disabled) globalMemCounter.disableAllocations();
+ }
+
+ void release() {
+ if (m_disabled) globalMemCounter.enableAllocations();
+ m_disabled = false;
+ }
+
+ ~DisableAllocationGuard() {
+ release();
+ }
+
+private:
+ bool m_disabled;
+
+ DisableAllocationGuard(DisableAllocationGuard const&);
+ DisableAllocationGuard& operator=(DisableAllocationGuard const&);
+};
+
#endif /* COUNT_NEW_HPP */
diff --git a/test/support/is_transparent.h b/test/support/is_transparent.h
new file mode 100644
index 0000000..5825524
--- /dev/null
+++ b/test/support/is_transparent.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 TRANSPARENT_H
+#define TRANSPARENT_H
+
+// testing transparent
+#if _LIBCPP_STD_VER > 11
+
+struct transparent_less
+{
+ template <class T, class U>
+ constexpr auto operator()(T&& t, U&& u) const
+ noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
+ -> decltype (std::forward<T>(t) < std::forward<U>(u))
+ { return std::forward<T>(t) < std::forward<U>(u); }
+ typedef void is_transparent; // correct
+};
+
+struct transparent_less_no_type
+{
+ template <class T, class U>
+ constexpr auto operator()(T&& t, U&& u) const
+ noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
+ -> decltype (std::forward<T>(t) < std::forward<U>(u))
+ { return std::forward<T>(t) < std::forward<U>(u); }
+private:
+// typedef void is_transparent; // error - should exist
+};
+
+struct transparent_less_private
+{
+ template <class T, class U>
+ constexpr auto operator()(T&& t, U&& u) const
+ noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
+ -> decltype (std::forward<T>(t) < std::forward<U>(u))
+ { return std::forward<T>(t) < std::forward<U>(u); }
+private:
+ typedef void is_transparent; // error - should be accessible
+};
+
+struct transparent_less_not_a_type
+{
+ template <class T, class U>
+ constexpr auto operator()(T&& t, U&& u) const
+ noexcept(noexcept(std::forward<T>(t) < std::forward<U>(u)))
+ -> decltype (std::forward<T>(t) < std::forward<U>(u))
+ { return std::forward<T>(t) < std::forward<U>(u); }
+
+ int is_transparent; // error - should be a type
+};
+
+struct C2Int { // comparable to int
+ C2Int() : i_(0) {}
+ C2Int(int i): i_(i) {}
+ int get () const { return i_; }
+private:
+ int i_;
+ };
+
+bool operator <(int rhs, const C2Int& lhs) { return rhs < lhs.get(); }
+bool operator <(const C2Int& rhs, const C2Int& lhs) { return rhs.get() < lhs.get(); }
+bool operator <(const C2Int& rhs, int lhs) { return rhs.get() < lhs; }
+
+#endif
+
+#endif // TRANSPARENT_H
diff --git a/test/support/min_allocator.h b/test/support/min_allocator.h
index b643636..5e3ae5d 100644
--- a/test/support/min_allocator.h
+++ b/test/support/min_allocator.h
@@ -12,16 +12,18 @@
#include <cstddef>
+#include "test_macros.h"
+
template <class T>
class bare_allocator
{
public:
typedef T value_type;
- bare_allocator() {}
+ bare_allocator() TEST_NOEXCEPT {}
template <class U>
- bare_allocator(bare_allocator<U>) {}
+ bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
T* allocate(std::size_t n)
{
@@ -53,10 +55,10 @@
{
const void* ptr_;
public:
- min_pointer() noexcept = default;
- min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
template <class T>
- min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
+ min_pointer(min_pointer<T> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
explicit operator bool() const {return ptr_ != nullptr;}
@@ -70,15 +72,15 @@
{
void* ptr_;
public:
- min_pointer() noexcept = default;
- min_pointer(std::nullptr_t) : ptr_(nullptr) {}
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
template <class T,
class = typename std::enable_if
<
!std::is_const<T>::value
>::type
>
- min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
+ min_pointer(min_pointer<T> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
explicit operator bool() const {return ptr_ != nullptr;}
@@ -92,11 +94,11 @@
{
T* ptr_;
- explicit min_pointer(T* p) : ptr_(p) {}
+ explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
public:
- min_pointer() noexcept = default;
- min_pointer(std::nullptr_t) : ptr_(nullptr) {}
- explicit min_pointer(min_pointer<void> p) : ptr_(static_cast<T*>(p.ptr_)) {}
+ min_pointer() TEST_NOEXCEPT = default;
+ min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
+ explicit min_pointer(min_pointer<void> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
explicit operator bool() const {return ptr_ != nullptr;}
@@ -164,7 +166,7 @@
explicit min_pointer(const T* p) : ptr_(p) {}
public:
- min_pointer() noexcept = default;
+ min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t) : ptr_(nullptr) {}
min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
explicit min_pointer(min_pointer<const void> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
diff --git a/test/support/platform_support.h b/test/support/platform_support.h
index 180765e..233e721 100644
--- a/test/support/platform_support.h
+++ b/test/support/platform_support.h
@@ -15,6 +15,8 @@
#ifndef PLATFORM_SUPPORT_H
#define PLATFORM_SUPPORT_H
+#include <__config>
+
// locale names
#ifdef _WIN32
// WARNING: Windows does not support UTF-8 codepages.
@@ -25,6 +27,16 @@
#define LOCALE_fr_CA_ISO8859_1 "French_Canada.1252"
#define LOCALE_ru_RU_UTF_8 "Russian_Russia.1251"
#define LOCALE_zh_CN_UTF_8 "Chinese_China.936"
+#elif defined(__CloudABI__)
+// Timezones are integrated into locales through LC_TIMEZONE_MASK on
+// CloudABI. LC_ALL_MASK can only be used if a timezone has also been
+// provided. UTC should be all right.
+#define LOCALE_en_US_UTF_8 "en_US.UTF-8@UTC"
+#define LOCALE_fr_FR_UTF_8 "fr_FR.UTF-8@UTC"
+#define LOCALE_fr_CA_ISO8859_1 "fr_CA.ISO-8859-1@UTC"
+#define LOCALE_cs_CZ_ISO8859_2 "cs_CZ.ISO-8859-2@UTC"
+#define LOCALE_ru_RU_UTF_8 "ru_RU.UTF-8@UTC"
+#define LOCALE_zh_CN_UTF_8 "zh_CN.UTF-8@UTC"
#else
#define LOCALE_en_US_UTF_8 "en_US.UTF-8"
#define LOCALE_fr_FR_UTF_8 "fr_FR.UTF-8"
@@ -55,6 +67,7 @@
}
#endif
+#ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
inline
std::string
get_temp_file_name()
@@ -80,5 +93,6 @@
return Name;
#endif
}
+#endif // _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
#endif // PLATFORM_SUPPORT_H
diff --git a/test/support/test_allocator.h b/test/support/test_allocator.h
index 683fac2..47ef1d5 100644
--- a/test/support/test_allocator.h
+++ b/test/support/test_allocator.h
@@ -17,6 +17,8 @@
#include <climits>
#include <cassert>
+#include "test_macros.h"
+
class test_alloc_base
{
protected:
@@ -72,10 +74,10 @@
}
++time_to_throw;
++alloc_count;
- return (pointer)std::malloc(n * sizeof(T));
+ return (pointer)::operator new(n * sizeof(T));
}
void deallocate(pointer p, size_type n)
- {assert(data_ >= 0); --alloc_count; std::free(p);}
+ {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p);}
size_type max_size() const throw()
{return UINT_MAX / sizeof(T);}
void construct(pointer p, const T& val)
@@ -132,10 +134,10 @@
}
++time_to_throw;
++alloc_count;
- return (pointer)std::malloc(n * sizeof(T));
+ return (pointer)::operator new (n * sizeof(T));
}
void deallocate(pointer p, size_type n)
- {assert(data_ >= 0); --alloc_count; std::free(p);}
+ {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p); }
size_type max_size() const throw()
{return UINT_MAX / sizeof(T);}
void construct(pointer p, const T& val)
@@ -198,9 +200,9 @@
template <class U> other_allocator(const other_allocator<U>& a)
: data_(a.data_) {}
T* allocate(std::size_t n)
- {return (T*)std::malloc(n * sizeof(T));}
+ {return (T*)::operator new(n * sizeof(T));}
void deallocate(T* p, std::size_t n)
- {std::free(p);}
+ {::operator delete((void*)p);}
other_allocator select_on_container_copy_construction() const
{return other_allocator(-2);}
diff --git a/test/support/test_macros.h b/test/support/test_macros.h
new file mode 100644
index 0000000..08ec28f
--- /dev/null
+++ b/test/support/test_macros.h
@@ -0,0 +1,97 @@
+// -*- C++ -*-
+//===---------------------------- test_macros.h ---------------------------===//
+//
+// 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 SUPPORT_TEST_MACROS_HPP
+#define SUPPORT_TEST_MACROS_HPP
+
+#define TEST_CONCAT1(X, Y) X##Y
+#define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y)
+
+#ifdef __has_feature
+#define TEST_HAS_FEATURE(X) __has_feature(X)
+#else
+#define TEST_HAS_FEATURE(X) 0
+#endif
+
+#ifdef __has_extension
+#define TEST_HAS_EXTENSION(X) __has_extension(X)
+#else
+#define TEST_HAS_EXTENSION(X) 0
+#endif
+
+/* Make a nice name for the standard version */
+#if __cplusplus <= 199711L
+# define TEST_STD_VER 3
+#elif __cplusplus <= 201103L
+# define TEST_STD_VER 11
+#elif __cplusplus <= 201402L
+# define TEST_STD_VER 14
+#else
+# define TEST_STD_VER 99 // greater than current standard
+#endif
+
+/* Features that were introduced in C++11 */
+#if TEST_STD_VER >= 11
+#define TEST_HAS_RVALUE_REFERENCES
+#define TEST_HAS_VARIADIC_TEMPLATES
+#define TEST_HAS_INITIALIZER_LISTS
+#define TEST_HAS_BASIC_CONSTEXPR
+#endif
+
+/* Features that were introduced in C++14 */
+#if TEST_STD_VER >= 14
+#define TEST_HAS_EXTENDED_CONSTEXPR
+#define TEST_HAS_VARIABLE_TEMPLATES
+#endif
+
+/* Features that were introduced after C++14 */
+#if TEST_STD_VER > 14
+#endif
+
+#if TEST_HAS_EXTENSION(cxx_decltype) || TEST_STD_VER >= 11
+#define TEST_DECLTYPE(T) decltype(T)
+#else
+#define TEST_DECLTYPE(T) __typeof__(T)
+#endif
+
+#if TEST_STD_VER >= 11
+#define TEST_NOEXCEPT noexcept
+#else
+#define TEST_NOEXCEPT
+#endif
+
+#if TEST_HAS_EXTENSION(cxx_static_assert) || TEST_STD_VER >= 11
+# define TEST_STATIC_ASSERT(Expr, Msg) static_assert(Expr, Msg)
+#else
+# define TEST_STATIC_ASSERT(Expr, Msg) \
+ typedef ::test_detail::static_assert_check<sizeof( \
+ ::test_detail::static_assert_incomplete_test<(Expr)>)> \
+ TEST_CONCAT(test_assert, __LINE__)
+#
+#endif
+
+namespace test_detail {
+
+template <bool> struct static_assert_incomplete_test;
+template <> struct static_assert_incomplete_test<true> {};
+template <unsigned> struct static_assert_check {};
+
+} // end namespace test_detail
+
+
+#if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cxx_rtti)
+#define TEST_HAS_NO_RTTI
+#endif
+
+#if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cxx_exceptions)
+#define TEST_HAS_NO_EXCEPTIONS
+#endif
+
+#endif // SUPPORT_TEST_MACROS_HPP
diff --git a/test/support/tracked_value.h b/test/support/tracked_value.h
new file mode 100644
index 0000000..b0869b2
--- /dev/null
+++ b/test/support/tracked_value.h
@@ -0,0 +1,50 @@
+#ifndef SUPPORT_TRACKED_VALUE_H
+#define SUPPORT_TRACKED_VALUE_H
+
+#include <cassert>
+
+struct TrackedValue {
+ enum State { CONSTRUCTED, MOVED_FROM, DESTROYED };
+ State state;
+
+ TrackedValue() : state(State::CONSTRUCTED) {}
+
+ TrackedValue(TrackedValue const& t) : state(State::CONSTRUCTED) {
+ assert(t.state != State::MOVED_FROM && "copying a moved-from object");
+ assert(t.state != State::DESTROYED && "copying a destroyed object");
+ }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ TrackedValue(TrackedValue&& t) : state(State::CONSTRUCTED) {
+ assert(t.state != State::MOVED_FROM && "double moving from an object");
+ assert(t.state != State::DESTROYED && "moving from a destroyed object");
+ t.state = State::MOVED_FROM;
+ }
+#endif
+
+ TrackedValue& operator=(TrackedValue const& t) {
+ assert(state != State::DESTROYED && "copy assigning into destroyed object");
+ assert(t.state != State::MOVED_FROM && "copying a moved-from object");
+ assert(t.state != State::DESTROYED && "copying a destroyed object");
+ state = t.state;
+ return *this;
+ }
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ TrackedValue& operator=(TrackedValue&& t) {
+ assert(state != State::DESTROYED && "move assigning into destroyed object");
+ assert(t.state != State::MOVED_FROM && "double moving from an object");
+ assert(t.state != State::DESTROYED && "moving from a destroyed object");
+ state = t.state;
+ t.state = State::MOVED_FROM;
+ return *this;
+ }
+#endif
+
+ ~TrackedValue() {
+ assert(state != State::DESTROYED && "double-destroying an object");
+ state = State::DESTROYED;
+ }
+};
+
+#endif // SUPPORT_TRACKED_VALUE_H
diff --git a/utils/sym_check/linux_blacklist.txt b/utils/sym_check/linux_blacklist.txt
new file mode 100644
index 0000000..4d9d1d4
--- /dev/null
+++ b/utils/sym_check/linux_blacklist.txt
@@ -0,0 +1,19 @@
+# all guard variables
+_ZGVNSt3__
+# all vtables
+_ZTV
+# all VTT
+_ZTT
+# all non-virtual thunks
+_ZTh
+# all virtual thunks
+_ZTv
+# typeinfo for std::__1::__types
+# There are no std::__types
+_ZTINSt3__1[0-9][0-9]*__
+# typeinfo name for std::__1::__types
+_ZTSNSt3__1[0-9][0-9]*__
+# anything using __hidden_allocator
+.*__hidden_allocator
+# anything using __sso_allocator
+.*__sso_allocator
diff --git a/utils/sym_check/osx_blacklist.txt b/utils/sym_check/osx_blacklist.txt
new file mode 100644
index 0000000..cfa911e
--- /dev/null
+++ b/utils/sym_check/osx_blacklist.txt
@@ -0,0 +1,19 @@
+# all guard variables
+__ZGVNSt3__
+# all vtables
+__ZTV
+# all VTT
+__ZTT
+# all non-virtual thunks
+__ZTh
+# all virtual thunks
+__ZTv
+# typeinfo for std::__1::__types
+# There are no std::__types
+__ZTINSt3__1[0-9][0-9]*__
+# typeinfo name for std::__1::__types
+__ZTSNSt3__1[0-9][0-9]*__
+# anything using __hidden_allocator
+.*__hidden_allocator
+# anything using __sso_allocator
+.*__sso_allocator
diff --git a/utils/sym_check/sym_check/__init__.py b/utils/sym_check/sym_check/__init__.py
new file mode 100644
index 0000000..3c66803
--- /dev/null
+++ b/utils/sym_check/sym_check/__init__.py
@@ -0,0 +1,8 @@
+"""libcxx abi symbol checker"""
+
+__author__ = 'Eric Fiselier'
+__email__ = 'eric@efcs.ca'
+__versioninfo__ = (0, 1, 0)
+__version__ = ' '.join(str(v) for v in __versioninfo__) + 'dev'
+
+__all__ = ['diff', 'extract', 'util']
diff --git a/utils/sym_check/sym_check/diff.py b/utils/sym_check/sym_check/diff.py
new file mode 100644
index 0000000..a16e54d
--- /dev/null
+++ b/utils/sym_check/sym_check/diff.py
@@ -0,0 +1,93 @@
+# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:
+"""
+diff - A set of functions for diff-ing two symbol lists.
+"""
+
+from sym_check import util
+
+
+def _symbol_difference(lhs, rhs):
+ lhs_names = set((n['name'] for n in lhs))
+ rhs_names = set((n['name'] for n in rhs))
+ diff_names = lhs_names - rhs_names
+ return [n for n in lhs if n['name'] in diff_names]
+
+
+def _find_by_key(sym_list, k):
+ for sym in sym_list:
+ if sym['name'] == k:
+ return sym
+ return None
+
+
+def added_symbols(old, new):
+ return _symbol_difference(new, old)
+
+
+def removed_symbols(old, new):
+ return _symbol_difference(old, new)
+
+
+def changed_symbols(old, new):
+ changed = []
+ for old_sym in old:
+ if old_sym in new:
+ continue
+ new_sym = _find_by_key(new, old_sym['name'])
+ if (new_sym is not None and not new_sym in old
+ and cmp(old_sym, new_sym) != 0):
+ changed += [(old_sym, new_sym)]
+ return changed
+
+
+def diff(old, new):
+ added = added_symbols(old, new)
+ removed = removed_symbols(old, new)
+ changed = changed_symbols(old, new)
+ return added, removed, changed
+
+
+def report_diff(added_syms, removed_syms, changed_syms, names_only=False,
+ demangle=True):
+ def maybe_demangle(name):
+ return util.demangle_symbol(name) if demangle else name
+
+ report = ''
+ for sym in added_syms:
+ report += 'Symbol added: %s\n' % maybe_demangle(sym['name'])
+ if not names_only:
+ report += ' %s\n\n' % sym
+ if added_syms and names_only:
+ report += '\n'
+ for sym in removed_syms:
+ report += 'SYMBOL REMOVED: %s\n' % maybe_demangle(sym['name'])
+ if not names_only:
+ report += ' %s\n\n' % sym
+ if removed_syms and names_only:
+ report += '\n'
+ if not names_only:
+ for sym_pair in changed_syms:
+ old_sym, new_sym = sym_pair
+ old_str = '\n OLD SYMBOL: %s' % old_sym
+ new_str = '\n NEW SYMBOL: %s' % new_sym
+ report += ('SYMBOL CHANGED: %s%s%s\n\n' %
+ (maybe_demangle(old_sym['name']),
+ old_str, new_str))
+
+ added = bool(len(added_syms) != 0)
+ abi_break = bool(len(removed_syms))
+ if not names_only:
+ abi_break = abi_break or len(changed_syms)
+ if added or abi_break:
+ report += 'Summary\n'
+ report += ' Added: %d\n' % len(added_syms)
+ report += ' Removed: %d\n' % len(removed_syms)
+ if not names_only:
+ report += ' Changed: %d\n' % len(changed_syms)
+ if not abi_break:
+ report += 'Symbols added.'
+ else:
+ report += 'ABI BREAKAGE: SYMBOLS ADDED OR REMOVED!'
+ else:
+ report += 'Symbols match.'
+ return report, int(abi_break)
diff --git a/utils/sym_check/sym_check/extract.py b/utils/sym_check/sym_check/extract.py
new file mode 100644
index 0000000..b4f4cee
--- /dev/null
+++ b/utils/sym_check/sym_check/extract.py
@@ -0,0 +1,177 @@
+# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:
+"""
+extract - A set of function that extract symbol lists from shared libraries.
+"""
+import distutils.spawn
+import sys
+
+from sym_check import util
+
+
+class NMExtractor(object):
+ """
+ NMExtractor - Extract symbol lists from libraries using nm.
+ """
+
+ @staticmethod
+ def find_tool():
+ """
+ Search for the nm executable and return the path.
+ """
+ return distutils.spawn.find_executable('nm')
+
+ def __init__(self):
+ """
+ Initialize the nm executable and flags that will be used to extract
+ symbols from shared libraries.
+ """
+ self.nm_exe = self.find_tool()
+ if self.nm_exe is None:
+ # ERROR no NM found
+ print("ERROR: Could not find nm")
+ sys.exit(1)
+ self.flags = ['-P', '-g']
+
+ def extract(self, lib):
+ """
+ Extract symbols from a library and return the results as a dict of
+ parsed symbols.
+ """
+ cmd = [self.nm_exe] + self.flags + [lib]
+ out, _, exit_code = util.execute_command_verbose(cmd)
+ if exit_code != 0:
+ raise RuntimeError('Failed to run %s on %s' % (self.nm_exe, lib))
+ fmt_syms = (self._extract_sym(l)
+ for l in out.splitlines() if l.strip())
+ # Cast symbol to string.
+ final_syms = (repr(s) for s in fmt_syms if self._want_sym(s))
+ # Make unique and sort strings.
+ tmp_list = list(sorted(set(final_syms)))
+ # Cast string back to symbol.
+ return util.read_syms_from_list(tmp_list)
+
+ def _extract_sym(self, sym_str):
+ bits = sym_str.split()
+ # Everything we want has at least two columns.
+ if len(bits) < 2:
+ return None
+ new_sym = {
+ 'name': bits[0],
+ 'type': bits[1]
+ }
+ new_sym['name'] = new_sym['name'].replace('@@', '@')
+ new_sym = self._transform_sym_type(new_sym)
+ # NM types which we want to save the size for.
+ if new_sym['type'] == 'OBJECT' and len(bits) > 3:
+ new_sym['size'] = int(bits[3], 16)
+ return new_sym
+
+ @staticmethod
+ def _want_sym(sym):
+ """
+ Check that s is a valid symbol that we want to keep.
+ """
+ if sym is None or len(sym) < 2:
+ return False
+ bad_types = ['t', 'b', 'r', 'd', 'w']
+ return (sym['type'] not in bad_types
+ and sym['name'] not in ['__bss_start', '_end', '_edata'])
+
+ @staticmethod
+ def _transform_sym_type(sym):
+ """
+ Map the nm single letter output for type to either FUNC or OBJECT.
+ If the type is not recognized it is left unchanged.
+ """
+ func_types = ['T', 'W']
+ obj_types = ['B', 'D', 'R', 'V', 'S']
+ if sym['type'] in func_types:
+ sym['type'] = 'FUNC'
+ elif sym['type'] in obj_types:
+ sym['type'] = 'OBJECT'
+ return sym
+
+class ReadElfExtractor(object):
+ """
+ ReadElfExtractor - Extract symbol lists from libraries using readelf.
+ """
+
+ @staticmethod
+ def find_tool():
+ """
+ Search for the readelf executable and return the path.
+ """
+ return distutils.spawn.find_executable('readelf')
+
+ def __init__(self):
+ """
+ Initialize the readelf executable and flags that will be used to
+ extract symbols from shared libraries.
+ """
+ self.tool = self.find_tool()
+ if self.tool is None:
+ # ERROR no NM found
+ print("ERROR: Could not find readelf")
+ sys.exit(1)
+ self.flags = ['--wide', '--symbols']
+
+ def extract(self, lib):
+ """
+ Extract symbols from a library and return the results as a dict of
+ parsed symbols.
+ """
+ cmd = [self.tool] + self.flags + [lib]
+ out, _, exit_code = util.execute_command_verbose(cmd)
+ if exit_code != 0:
+ raise RuntimeError('Failed to run %s on %s' % (self.nm_exe, lib))
+ dyn_syms = self.get_dynsym_table(out)
+ return self.process_syms(dyn_syms)
+
+ def process_syms(self, sym_list):
+ new_syms = []
+ for s in sym_list:
+ parts = s.split()
+ if not parts:
+ continue
+ assert len(parts) == 7 or len(parts) == 8 or len(parts) == 9
+ if len(parts) == 7:
+ continue
+ new_sym = {
+ 'name': parts[7],
+ 'size': int(parts[2]),
+ 'type': parts[3],
+ }
+ assert new_sym['type'] in ['OBJECT', 'FUNC', 'NOTYPE']
+ if new_sym['type'] == 'NOTYPE':
+ continue
+ if new_sym['type'] == 'FUNC':
+ del new_sym['size']
+ new_syms += [new_sym]
+ return new_syms
+
+ def get_dynsym_table(self, out):
+ lines = out.splitlines()
+ start = -1
+ end = -1
+ for i in range(len(lines)):
+ if lines[i].startswith("Symbol table '.dynsym'"):
+ start = i + 2
+ if start != -1 and end == -1 and not lines[i].strip():
+ end = i + 1
+ assert start != -1
+ if end == -1:
+ end = len(lines)
+ return lines[start:end]
+
+
+def extract_symbols(lib_file):
+ """
+ Extract and return a list of symbols extracted from a dynamic library.
+ The symbols are extracted using NM. They are then filtered and formated.
+ Finally they symbols are made unique.
+ """
+ if ReadElfExtractor.find_tool():
+ extractor = ReadElfExtractor()
+ else:
+ extractor = NMExtractor()
+ return extractor.extract(lib_file)
diff --git a/utils/sym_check/sym_check/match.py b/utils/sym_check/sym_check/match.py
new file mode 100644
index 0000000..9f49642
--- /dev/null
+++ b/utils/sym_check/sym_check/match.py
@@ -0,0 +1,32 @@
+# -*- Python -*- vim: set syntax=python tabstop=4 expandtab cc=80:
+"""
+match - A set of functions for matching symbols in a list to a list of regexs
+"""
+
+import re
+
+
+def find_and_report_matching(symbol_list, regex_list):
+ report = ''
+ found_count = 0
+ for regex_str in regex_list:
+ report += 'Matching regex "%s":\n' % regex_str
+ matching_list = find_matching_symbols(symbol_list, regex_str)
+ if not matching_list:
+ report += ' No matches found\n\n'
+ continue
+ # else
+ found_count += len(matching_list)
+ for m in matching_list:
+ report += ' MATCHES: %s\n' % m['name']
+ report += '\n'
+ return found_count, report
+
+
+def find_matching_symbols(symbol_list, regex_str):
+ regex = re.compile(regex_str)
+ matching_list = []
+ for s in symbol_list:
+ if regex.match(s['name']):
+ matching_list += [s]
+ return matching_list
diff --git a/utils/sym_check/sym_check/util.py b/utils/sym_check/sym_check/util.py
new file mode 100644
index 0000000..1d3b424
--- /dev/null
+++ b/utils/sym_check/sym_check/util.py
@@ -0,0 +1,128 @@
+import ast
+import distutils.spawn
+import signal
+import subprocess
+import sys
+
+
+def execute_command(cmd, input_str=None):
+ """
+ Execute a command, capture and return its output.
+ """
+ kwargs = {
+ 'stdin': subprocess.PIPE,
+ 'stdout': subprocess.PIPE,
+ 'stderr': subprocess.PIPE,
+ }
+ p = subprocess.Popen(cmd, **kwargs)
+ out, err = p.communicate(input=input_str)
+ exitCode = p.wait()
+ if exitCode == -signal.SIGINT:
+ raise KeyboardInterrupt
+ return out, err, exitCode
+
+
+def execute_command_verbose(cmd, input_str=None):
+ """
+ Execute a command and print its output on failure.
+ """
+ out, err, exitCode = execute_command(cmd, input_str=input_str)
+ if exitCode != 0:
+ report = "Command: %s\n" % ' '.join(["'%s'" % a for a in cmd])
+ report += "Exit Code: %d\n" % exitCode
+ if out:
+ report += "Standard Output:\n--\n%s--" % out
+ if err:
+ report += "Standard Error:\n--\n%s--" % err
+ report += "\n\nFailed!"
+ sys.stderr.write('%s\n' % report)
+ return out, err, exitCode
+
+
+def read_syms_from_list(slist):
+ """
+ Read a list of symbols from a list of strings.
+ Each string is one symbol.
+ """
+ return [ast.literal_eval(l) for l in slist]
+
+
+def read_syms_from_file(filename):
+ """
+ Read a list of symbols in from a file.
+ """
+ with open(filename, 'r') as f:
+ data = f.read()
+ return read_syms_from_list(data.splitlines())
+
+
+def read_blacklist(filename):
+ with open(filename, 'r') as f:
+ data = f.read()
+ lines = [l.strip() for l in data.splitlines() if l.strip()]
+ lines = [l for l in lines if not l.startswith('#')]
+ return lines
+
+
+def write_syms(sym_list, out=None, names_only=False):
+ """
+ Write a list of symbols to the file named by out.
+ """
+ out_str = ''
+ out_list = sym_list
+ if names_only:
+ out_list = [sym['name'] for sym in sym_list]
+ out_list.sort()
+ for sym in out_list:
+ out_str += '%s\n' % sym
+ if out is None:
+ sys.stdout.write(out_str)
+ else:
+ with open(out, 'w') as f:
+ f.write(out_str)
+
+
+_cppfilt_exe = distutils.spawn.find_executable('c++filt')
+
+
+def demangle_symbol(symbol):
+ if _cppfilt_exe is None:
+ return symbol
+ out, _, exit_code = execute_command_verbose(
+ [_cppfilt_exe], input_str=symbol)
+ if exit_code != 0:
+ return symbol
+ return out
+
+
+def is_elf(filename):
+ with open(filename, 'r') as f:
+ magic_bytes = f.read(4)
+ return magic_bytes == '\x7fELF'
+
+
+def is_mach_o(filename):
+ with open(filename, 'r') as f:
+ magic_bytes = f.read(4)
+ return magic_bytes in [
+ '\xfe\xed\xfa\xce', # MH_MAGIC
+ '\xce\xfa\xed\xfe', # MH_CIGAM
+ '\xfe\xed\xfa\xcf', # MH_MAGIC_64
+ '\xcf\xfa\xed\xfe', # MH_CIGAM_64
+ '\xca\xfe\xba\xbe', # FAT_MAGIC
+ '\xbe\xba\xfe\xca' # FAT_CIGAM
+ ]
+
+
+def is_library_file(filename):
+ if sys.platform == 'darwin':
+ return is_mach_o(filename)
+ else:
+ return is_elf(filename)
+
+
+def extract_or_load(filename):
+ import sym_check.extract
+ if is_library_file(filename):
+ return sym_check.extract.extract_symbols(filename)
+ return read_syms_from_file(filename)
diff --git a/utils/sym_check/sym_diff.py b/utils/sym_check/sym_diff.py
new file mode 100755
index 0000000..054c6c1
--- /dev/null
+++ b/utils/sym_check/sym_diff.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+"""
+sym_diff - Compare two symbol lists and output the differences.
+"""
+from argparse import ArgumentParser
+import sys
+from sym_check import diff, util
+
+
+def main():
+ parser = ArgumentParser(
+ description='Extract a list of symbols from a shared library.')
+ parser.add_argument(
+ '--names-only', dest='names_only',
+ help='Only print symbol names',
+ action='store_true', default=False)
+ parser.add_argument(
+ '-o', '--output', dest='output',
+ help='The output file. stdout is used if not given',
+ type=str, action='store', default=None)
+ parser.add_argument(
+ '--demangle', dest='demangle', action='store_true', default=False)
+ parser.add_argument(
+ 'old_syms', metavar='old-syms', type=str,
+ help='The file containing the old symbol list or a library')
+ parser.add_argument(
+ 'new_syms', metavar='new-syms', type=str,
+ help='The file containing the new symbol list or a library')
+ args = parser.parse_args()
+
+ old_syms_list = util.extract_or_load(args.old_syms)
+ new_syms_list = util.extract_or_load(args.new_syms)
+
+ added, removed, changed = diff.diff(old_syms_list, new_syms_list)
+ report, is_break = diff.report_diff(added, removed, changed,
+ names_only=args.names_only,
+ demangle=args.demangle)
+ if args.output is None:
+ print(report)
+ else:
+ with open(args.output, 'w') as f:
+ f.write(report + '\n')
+ sys.exit(is_break)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/sym_check/sym_extract.py b/utils/sym_check/sym_extract.py
new file mode 100755
index 0000000..5d89539
--- /dev/null
+++ b/utils/sym_check/sym_extract.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+"""
+sym_extract - Extract and output a list of symbols from a shared library.
+"""
+from argparse import ArgumentParser
+from sym_check import extract, util
+
+
+def main():
+ parser = ArgumentParser(
+ description='Extract a list of symbols from a shared library.')
+ parser.add_argument('library', metavar='shared-lib', type=str,
+ help='The library to extract symbols from')
+ parser.add_argument('-o', '--output', dest='output',
+ help='The output file. stdout is used if not given',
+ type=str, action='store', default=None)
+ parser.add_argument('--names-only', dest='names_only',
+ help='Output only the name of the symbol',
+ action='store_true', default=False)
+ args = parser.parse_args()
+ if args.output is not None:
+ print('Extracting symbols from %s to %s.'
+ % (args.library, args.output))
+ syms = extract.extract_symbols(args.library)
+ util.write_syms(syms, out=args.output, names_only=args.names_only)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/sym_check/sym_match.py b/utils/sym_check/sym_match.py
new file mode 100755
index 0000000..c60b246
--- /dev/null
+++ b/utils/sym_check/sym_match.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+"""
+sym_match - Match all symbols in a list against a list of regexes.
+"""
+from argparse import ArgumentParser
+import sys
+from sym_check import util, match, extract
+
+
+def main():
+ parser = ArgumentParser(
+ description='Extract a list of symbols from a shared library.')
+ parser.add_argument(
+ '--blacklist', dest='blacklist',
+ type=str, action='store', default=None)
+ parser.add_argument(
+ 'symbol_list', metavar='symbol_list', type=str,
+ help='The file containing the old symbol list')
+ parser.add_argument(
+ 'regexes', metavar='regexes', default=[], nargs='*',
+ help='The file containing the new symbol list or a library')
+ args = parser.parse_args()
+
+ if not args.regexes and args.blacklist is None:
+ sys.stderr.write('Either a regex or a blacklist must be specified.\n')
+ sys.exit(1)
+ if args.blacklist:
+ search_list = util.read_blacklist(args.blacklist)
+ else:
+ search_list = args.regexes
+
+ symbol_list = util.extract_or_load(args.symbol_list)
+
+ matching_count, report = match.find_and_report_matching(
+ symbol_list, search_list)
+ sys.stdout.write(report)
+ if matching_count != 0:
+ print('%d matching symbols found...' % matching_count)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/www/atomic_design.html b/www/atomic_design.html
index 2314841..67021b8 100644
--- a/www/atomic_design.html
+++ b/www/atomic_design.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
diff --git a/www/atomic_design_a.html b/www/atomic_design_a.html
index b329fd1..8e9fef2 100644
--- a/www/atomic_design_a.html
+++ b/www/atomic_design_a.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
diff --git a/www/atomic_design_b.html b/www/atomic_design_b.html
index b738445..17ba9b3 100644
--- a/www/atomic_design_b.html
+++ b/www/atomic_design_b.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
diff --git a/www/atomic_design_c.html b/www/atomic_design_c.html
index f574d4d..9c92b88 100644
--- a/www/atomic_design_c.html
+++ b/www/atomic_design_c.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
diff --git a/www/cxx1y_status.html b/www/cxx1y_status.html
index ce7f216..2b9c05a 100644
--- a/www/cxx1y_status.html
+++ b/www/cxx1y_status.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
diff --git a/www/cxx1z_status.html b/www/cxx1z_status.html
index 16b16f7..4369810 100644
--- a/www/cxx1z_status.html
+++ b/www/cxx1z_status.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
@@ -54,14 +54,21 @@
-->
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3911">N3911</a></td><td>LWG</td></td><td>TransformationTrait Alias <code>void_t</code>.</td><td>Urbana</td><td>Complete</td><td>3.6</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4089">N4089</a></td><td>LWG</td></td><td>Safe conversions in <code>unique_ptr<T[]></code>.</td><td>Urbana</td><td></td><td></td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169">N4169</a></td><td>LWG</td></td><td>A proposal to add invoke function template</td><td>Urbana</td><td></td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169">N4169</a></td><td>LWG</td></td><td>A proposal to add invoke function template</td><td>Urbana</td><td>Complete</td><td>3.7</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190">N4190</a></td></td><td>LWG</td><td>Removing auto_ptr, random_shuffle(), And Old <functional> Stuff.</td><td>Urbana</td><td></td><td></td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4258.pdf">N4258</a></td><td>LWG</td></td><td>Cleaning-up noexcept in the Library.</td><td>Urbana</td><td></td><td></td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/N4277.html">N4277</a></td><td>LWG</td></td><td>TriviallyCopyable <code>reference_wrapper</code>.</td><td>Urbana</td><td>Complete</td><td>3.2</td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4279.html">N4279</a></td><td>LWG</td></td><td>Improved insertion interface for unique-key maps.</td><td>Urbana</td><td></td><td></td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4280.pdf">N4280</a></td><td>LWG</td></td><td>Non-member size() and more</td><td>Urbana</td><td>Complete</td><td>3.6</td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4284.html">N4284</a></td><td>LWG</td></td><td>Contiguous Iterators.</td><td>Urbana</td><td></td><td></td></tr>
-
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4258">N4258</a></td><td>LWG</td></td><td>Cleaning-up noexcept in the Library.</td><td>Urbana</td><td>In progress</td><td>3.7</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4259">N4259</a></td><td>CWG</td></td><td>Wording for std::uncaught_exceptions</td><td>Urbana</td><td>Complete</td><td>3.7</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4277">N4277</a></td><td>LWG</td></td><td>TriviallyCopyable <code>reference_wrapper</code>.</td><td>Urbana</td><td>Complete</td><td>3.2</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4279">N4279</a></td><td>LWG</td></td><td>Improved insertion interface for unique-key maps.</td><td>Urbana</td><td>Complete</td><td>3.7</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4280">N4280</a></td><td>LWG</td></td><td>Non-member size() and more</td><td>Urbana</td><td>Complete</td><td>3.6</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4284">N4284</a></td><td>LWG</td></td><td>Contiguous Iterators.</td><td>Urbana</td><td>Complete</td><td>3.6</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4285">N4285</a></td><td>CWG</td></td><td>Cleanup for exception-specification and throw-expression.</td><td>Urbana</td><td></td><td></td></tr>
+ <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4387">N4387</a></td><td>LWG</td></td><td>improving pair and tuple</td><td>Lenexa</td><td></td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4389">N4389</a></td><td>LWG</td></td><td>bool_constant</td><td>Lenexa</td><td>Complete</td><td>3.7</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4508">N4508</a></td><td>LWG</td></td><td>shared_mutex for C++17</td><td>Lenexa</td><td>Complete</td><td>3.7</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4366">N4366</a></td><td>LWG</td></td><td>LWG 2228 missing SFINAE rule</td><td>Lenexa</td><td>Complete</td><td>3.1</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4510">N4510</a></td><td>LWG</td></td><td>Minimal incomplete type support for standard containers, revision 4</td><td>Lenexa</td><td>Complete</td><td>3.6</td></tr>
<!-- <tr><td></td><td></td><td></td><td></td><td></td><td></td></tr> -->
</table>
@@ -71,38 +78,74 @@
<tr><th>Issue #</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2016">2016</a></td><td>Allocators must be no-throw swappable</td><td>Urbana</td><td></td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2376">2118</td><td><code>unique_ptr</code> for array does not support cv qualification conversion of actual argument</td><td>Urbana</td><td>Will be resolved by N4089</td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td></td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2387">2308</td><td>Clarify container destructor requirements w.r.t. <code>std::array</code></td><td>Urbana</td><td>Will be resolved by N4258</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2308">2308</td><td>Clarify container destructor requirements w.r.t. <code>std::array</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2340">2340</a></td><td>Replacement allocation functions declared as inline</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2354">2354</a></td><td>Unnecessary copying when inserting into maps with braced-init syntax</td><td>Urbana</td><td></td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2396">2396</a></td><td><code>underlying_type</code> doesn't say what to do for an incomplete enumeration type</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2399">2399</a></td><td><code>shared_ptr</code>'s constructor from <code>unique_ptr</code> should be constrained</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2400">2400</a></td><td><code>shared_ptr</code>'s <code>get_deleter()</code> should use <code>addressof()</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2401">2401</a></td><td><code>std::function</code> needs more noexcept</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2404">2404</a></td><td><code>mismatch()</code>'s complexity needs to be updated</td><td>Urbana</td><td>Complete</td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2408">2408</a></td><td>SFINAE-friendly <code>common_type</code> / <code>iterator_traits</code> is missing in C++14</td><td>Urbana</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2408">2408</a></td><td>SFINAE-friendly <code>common_type</code> / <code>iterator_traits</code> is missing in C++14</td><td>Urbana</td><td><code>common_type</code> is waiting on <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2465">LWG#2465</a></td></tr>
<tr><td></td><td></td><td></td><td></td></tr>
-
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2106">2106</td><td><code>move_iterator</code> wrapping iterators returning prvalues</td><td>Urbana</td><td></td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2129">2129</td><td>User specializations of <code>std::initializer_list</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2212">2212</td><td><code>tuple_size</code> for <code>const pair</code> request <tuple> header</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2217">2217</td><td><code>operator==(sub_match, string)</code> slices on embedded '\0's</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2230">2230</td><td>"see below" for <code>initializer_list</code> constructors of unordered containers</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2233">2233</td><td><code>bad_function_call::what()</code> unhelpful</td><td>Urbana</td><td>Complete</td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2266">2266</td><td><code>vector</code> and <code>deque</code> have incorrect insert requirements</td><td>Urbana</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2266">2266</td><td><code>vector</code> and <code>deque</code> have incorrect insert requirements</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2325">2325</td><td><code>minmax_element()</code>'s behavior differing from <code>max_element()</code>'s should be noted</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2361">2361</td><td>Apply 2299 resolution throughout library</td><td>Urbana</td><td></td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2365">2365</td><td>Missing noexcept in <code>shared_ptr::shared_ptr(nullptr_t)</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2376">2376</td><td><code>bad_weak_ptr::what()</code> overspecified</td><td>Urbana</td><td>Complete</td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2387">2387</td><td>More nested types that must be accessible and unambiguous</td><td>Urbana</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2387">2387</td><td>More nested types that must be accessible and unambiguous</td><td>Urbana</td><td>Complete</td></tr>
+ <tr><td></td><td></td><td></td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2059">2059</td><td>C++0x ambiguity problem with map::erase</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2063">2063</td><td>Contradictory requirements for string move assignment</td><td>Lenexa</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2076">2076</td><td>Bad CopyConstructible requirement in set constructors</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2160">2160</td><td>Unintended destruction ordering-specification of resize</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2168">2168</td><td>Inconsistent specification of uniform_real_distribution constructor</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2239">2239</td><td>min/max/minmax requirements</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2364">2364</td><td>deque and vector pop_back don't specify iterator invalidation requirements</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2369">2369</td><td>constexpr max(initializer_list) vs max_element</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2378">2378</td><td>Behaviour of standard exception types</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2403">2403</td><td>stof() should call strtof() and wcstof()</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2406">2406</td><td>negative_binomial_distribution should reject p == 1</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2407">2407</td><td>packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2411">2411</td><td>shared_ptr is only contextually convertible to bool</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2415">2415</td><td>Inconsistency between unique_ptr and shared_ptr</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2420">2420</td><td>function<void(ArgTypes...)> does not discard the return value of the target object</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2425">2425</td><td>operator delete(void*, size_t) doesn't invalidate pointers sufficiently</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2427">2427</td><td>Container adaptors as sequence containers, redux</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2428">2428</td><td>"External declaration" used without being defined</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2433">2433</td><td>uninitialized_copy()/etc. should tolerate overloaded operator&</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2434">2434</td><td>shared_ptr::use_count() is efficient</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2437">2437</td><td>iterator_traits::reference can and can't be void</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2438">2438</td><td>std::iterator inheritance shouldn't be mandated</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2439">2439</td><td>unique_copy() sometimes can't fall back to reading its output</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2440">2440</td><td>seed_seq::size() should be noexcept</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2442">2442</td><td>call_once() shouldn't DECAY_COPY()</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2448">2448</td><td>Non-normative Container destructor specification</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2454">2454</td><td>Add raw_storage_iterator::base() member</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2455">2455</td><td>Allocator default construction should be allowed to throw</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2458">2458</td><td>N3778 and new library deallocation signatures</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2459">2459</td><td>std::polar should require a non-negative rho</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2464">2464</td><td>try_emplace and insert_or_assign misspecified</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2467">2467</td><td>is_always_equal has slightly inconsistent default</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2470">2470</td><td>Allocator's destroy function should be allowed to fail to instantiate</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2482">2482</td><td>[c.strings] Table 73 mentions nonexistent functions</td><td>Lenexa</td><td>Complete</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2488">2488</td><td>Placeholders should be allowed and encouraged to be constexpr</td><td>Lenexa</td><td></td></tr>
+
<!--
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1214">1214</a></td><td>Insufficient/inconsistent key immutability requirements for associative containers</td><td>Urbana</td><td></td></tr>
-->
<!-- <tr><td></td><td></td><td></td><td></td></tr> -->
</table>
- <p>Last Updated: 18-Nov-2014</p>
+ <p>Last Updated: 27-May-2015</p>
</div>
</body>
</html>
diff --git a/www/index.html b/www/index.html
index c608183..798d0c8 100644
--- a/www/index.html
+++ b/www/index.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
@@ -184,26 +184,30 @@
<p>In-tree build:</p>
<ul>
+ <li><code>cd where-you-want-to-live</code></li>
<li>Check out libcxx and <a href="http://libcxxabi.llvm.org/">libcxxabi</a>
into llvm/projects</li>
- <li><code>cd llvm</code></li>
+ <li><code>cd where-you-want-to-build</code></li>
<li><code>mkdir build && cd build</code></li>
- <li><code>cmake .. # Linux may require -DCMAKE_C_COMPILER=clang
+ <li><code>cmake path/to/llvm # Linux may require -DCMAKE_C_COMPILER=clang
-DCMAKE_CXX_COMPILER=clang++</code></li>
<li><code>make cxx</code></li>
</ul>
- <p>Out-of-tree build:</p>
+ <p>Out-of-tree buildc:</p>
<ul>
- <li>Check out libcxx</li>
+ <li><code>cd where-you-want-to-live</code></li>
+ <li>Check out libcxx and llvm</li>
<li>If not on a Mac, also check out
<a href="http://libcxxabi.llvm.org/">libcxxabi</a></li>
- <li><code>cd libcxx</code></li>
+ <li><code>cd where-you-want-to-build</code></li>
<li><code>mkdir build && cd build</code></li>
- <li><code>cmake -DLIBCXX_CXX_ABI=libcxxabi
- -DLIBCXX_LIBCXXABI_INCLUDE_PATHS=path/to/libcxxabi/include
- -DLIT_EXECUTABLE=path/to/llvm/utils/lit/lit.py .. # Linux may require
- -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++</code></li>
+ <li><code>cmake -DLLVM_PATH=path/to/llvm
+ -DLIBCXX_CXX_ABI=libcxxabi
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxabi/include
+ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
+ path/to/libcxx
+ </code></li>
<li><code>make</code></li>
</ul>
@@ -239,21 +243,30 @@
<p>
Mac users, remember to be careful when replacing the system's libc++.
- <strong>Your system will not be able to boot without a funcioning
+ <strong>Your system will not be able to boot without a functioning
libc++.</strong>
</p>
<!--=====================================================================-->
- <h3>Notes</h3>
+ <h3>Notes and Known Issues</h3>
<!--=====================================================================-->
<p>
- Building libc++ with <code>-fno-rtti</code> is not supported. However
- linking against it with <code>-fno-rtti</code> is supported.
+ <ul>
+ <li>
+ Building libc++ with <code>-fno-rtti</code> is not supported. However
+ linking against it with <code>-fno-rtti</code> is supported.
+ </li>
+ <li>
+ On OS X v10.8 and older the CMake option
+ <code>-DLIBCXX_LIBCPPABI_VERSION=""</code> must be used during
+ configuration.
+ </li>
+ </ul>
</p>
<p>Send discussions to the
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">clang mailing list</a>.</p>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">clang mailing list</a>.</p>
<!--=====================================================================-->
<h2>Using libc++ in your programs</h2>
@@ -321,7 +334,7 @@
<p>
If you think you've found a bug in libc++, please report it using
the <a href="http://llvm.org/bugs">LLVM Bugzilla</a>. If you're not sure, you
- can post a message to the <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
+ can post a message to the <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
mailing list or on IRC. Please include "libc++" in your subject.
</p>
@@ -373,7 +386,7 @@
<ul>
<li><code>CC=clang CXX=clang++ cmake -G "Unix Makefiles"
-DLIBCXX_CXX_ABI=libstdc++
- -DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/"
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/"
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX=/usr
<libc++-source-dir></code></li>
@@ -408,7 +421,7 @@
<ul>
<li><code>CC=clang CXX=clang++ cmake -G "Unix Makefiles"
-DLIBCXX_CXX_ABI=libcxxrt
- -DLIBCXX_LIBCXXRT_INCLUDE_PATHS="<libcxxrt-source-dir>/src"
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="<libcxxrt-source-dir>/src"
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX=/usr
<libc++-source-dir></code></li>
@@ -450,7 +463,7 @@
<ul>
<li><code>CC=clang CXX=clang++ cmake
-DLIBCXX_CXX_ABI=libc++abi
- -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="/path/to/libcxxabi/include"
+ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/path/to/libcxxabi/include"
-DLIBCXX_CXX_ABI_LIBRARY_PATH="/path/to/libcxxabi-build/lib"
path/to/libcxx</code></li>
<li><code>make</code></li>
diff --git a/www/lit_usage.html b/www/lit_usage.html
index c6bfbae..2fcb2d0 100644
--- a/www/lit_usage.html
+++ b/www/lit_usage.html
@@ -37,8 +37,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
diff --git a/www/ts1z_status.html b/www/ts1z_status.html
index d3d29c2..b92f053 100644
--- a/www/ts1z_status.html
+++ b/www/ts1z_status.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>
@@ -47,10 +47,10 @@
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3940.html">3940</a></td><td>Technical Specification - File System</td><td>File System</td></tr>
<tr><td></td><td></td><td></td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/n4273.txt">4273</a></td><td>Uniform Container Erasure.</td><td>Library Fundamentals 2</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4273">4273</a></td><td>Uniform Container Erasure.</td><td>Library Fundamentals 2</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4061">4061</a></td><td>Greatest Common Divisor and Least Common Multiple.</td><td>Library Fundamentals 2</td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/N4257.htm">4257</a></td><td>Delimited iterators.</td><td>Library Fundamentals 2</td></tr>
- <tr><td><a href="http://wiki.edg.com/twiki/pub/Wg21urbana-champaign/StrawPolls/N4282.pdf">4282</a></td><td>The World's Dumbest Smart Pointer.</td><td>Library Fundamentals 2</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4257">4257</a></td><td>Delimited iterators.</td><td>Library Fundamentals 2</td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4282">4282</a></td><td>The World's Dumbest Smart Pointer.</td><td>Library Fundamentals 2</td></tr>
<tr><td></td><td></td><td></td></tr>
</table>
@@ -61,24 +61,23 @@
<tr><td>Uses-allocator construction</td><td>Not started</td></tr>
<tr><td>Changes to std::shared_ptr and weak_ptr</td><td>Not started</td></tr>
<tr><td>Additions to std::function</td><td>Not started</td></tr>
- <tr><td>Changes to std::common_type</td><td>Not started</td></tr>
- <tr><td>Changes to std::iterator_traits</td><td>Not started</td></tr>
<tr><td>Additions to std::promise</td><td>Not started</td></tr>
<tr><td>Additions to std::packaged_task</td><td>Not started</td></tr>
<tr><td></td><td></td></tr>
<tr><td>Class erased_type</td><td>Complete</td></tr>
- <tr><td>Calling a function with a tuple of arguments</td><td>Implementation in progress</td></tr>
+ <tr><td>Calling a function with a tuple of arguments</td><td>Complete</td></tr>
+ <tr><td>Type traits (_v)</td><td>Complete</td></tr>
<tr><td>Other type transformations</td><td>Not started</td></tr>
<tr><td>Compile-time Rational Arithmetic</td><td>Implementation in progress</td></tr>
<tr><td>Time Utilities</td><td>Complete</td></tr>
<tr><td>System Error Support</td><td>Complete</td></tr>
<tr><td></td><td></td></tr>
- <tr><td>Searchers</td><td>Not started</td></tr>
+ <tr><td>Searchers</td><td>Implementation in progress</td></tr>
<tr><td>Optional Objects</td><td>Initial implementation complete</td></tr>
- <tr><td>class any</td><td>Implementation in progress</td></tr>
- <tr><td>string_view</td><td>Implementation in progress</td></tr>
+ <tr><td>class any</td><td>Complete</td></tr>
+ <tr><td>string_view</td><td>Complete</td></tr>
<tr><td>memory</td><td>Implementation in progress</td></tr>
- <tr><td>Algorithms library</td><td>Not started</td></tr>
+ <tr><td>Algorithms library</td><td>Complete</td></tr>
</table>
@@ -96,7 +95,7 @@
</table>
- <p>Last Updated: 2-June-2014</p>
+ <p>Last Updated: 21-Jul-2015</p>
</div>
</body>
</html>
diff --git a/www/type_traits_design.html b/www/type_traits_design.html
index ea173a8..422bba4 100644
--- a/www/type_traits_design.html
+++ b/www/type_traits_design.html
@@ -22,8 +22,8 @@
<div class="submenu">
<label>Quick Links</label>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev</a>
- <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-dev">cfe-dev</a>
+ <a href="http://lists.llvm.org/mailman/listinfo/cfe-commits">cfe-commits</a>
<a href="http://llvm.org/bugs/">Bug Reports</a>
<a href="http://llvm.org/svn/llvm-project/libcxx/trunk/">Browse SVN</a>
<a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/">Browse ViewVC</a>